Commit 47c16975 authored by Mattias Wallin's avatar Mattias Wallin Committed by Samuel Ortiz

mfd: Align ab8500 with the abx500 interface

This patch makes the ab8500 mixed signal chip expose the same
interface for register access as the ab3100, ab3550 and ab5500 chip.
The ab8500_read() and ab8500_write() is removed and replaced with
abx500_get_register_interruptible() and
abx500_set_register_interruptible().
Signed-off-by: default avatarMattias Wallin <mattias.wallin@stericsson.com>
Acked-by: default avatarLinus Walleij <linus.walleij@stericsson.com>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent f4ebcab3
...@@ -434,7 +434,7 @@ config PCF50633_GPIO ...@@ -434,7 +434,7 @@ config PCF50633_GPIO
config ABX500_CORE config ABX500_CORE
bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
default y if ARCH_U300 default y if ARCH_U300 || ARCH_U8500
help help
Say yes here if you have the ABX500 Mixed Signal IC family Say yes here if you have the ABX500 Mixed Signal IC family
chips. This core driver expose register access functions. chips. This core driver expose register access functions.
...@@ -475,7 +475,7 @@ config EZX_PCAP ...@@ -475,7 +475,7 @@ config EZX_PCAP
config AB8500_CORE config AB8500_CORE
bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
depends on SPI=y && GENERIC_HARDIRQS depends on SPI=y && GENERIC_HARDIRQS && ABX500_CORE
select MFD_CORE select MFD_CORE
help help
Select this option to enable access to AB8500 power management Select this option to enable access to AB8500 power management
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* License Terms: GNU General Public License v2 * License Terms: GNU General Public License v2
* Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
* Author: Rabin Vincent <rabin.vincent@stericsson.com> * Author: Rabin Vincent <rabin.vincent@stericsson.com>
* Changes: Mattias Wallin <mattias.wallin@stericsson.com>
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -15,6 +16,7 @@ ...@@ -15,6 +16,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/ab8500.h> #include <linux/mfd/ab8500.h>
#include <linux/regulator/ab8500.h> #include <linux/regulator/ab8500.h>
...@@ -22,71 +24,71 @@ ...@@ -22,71 +24,71 @@
* Interrupt register offsets * Interrupt register offsets
* Bank : 0x0E * Bank : 0x0E
*/ */
#define AB8500_IT_SOURCE1_REG 0x0E00 #define AB8500_IT_SOURCE1_REG 0x00
#define AB8500_IT_SOURCE2_REG 0x0E01 #define AB8500_IT_SOURCE2_REG 0x01
#define AB8500_IT_SOURCE3_REG 0x0E02 #define AB8500_IT_SOURCE3_REG 0x02
#define AB8500_IT_SOURCE4_REG 0x0E03 #define AB8500_IT_SOURCE4_REG 0x03
#define AB8500_IT_SOURCE5_REG 0x0E04 #define AB8500_IT_SOURCE5_REG 0x04
#define AB8500_IT_SOURCE6_REG 0x0E05 #define AB8500_IT_SOURCE6_REG 0x05
#define AB8500_IT_SOURCE7_REG 0x0E06 #define AB8500_IT_SOURCE7_REG 0x06
#define AB8500_IT_SOURCE8_REG 0x0E07 #define AB8500_IT_SOURCE8_REG 0x07
#define AB8500_IT_SOURCE19_REG 0x0E12 #define AB8500_IT_SOURCE19_REG 0x12
#define AB8500_IT_SOURCE20_REG 0x0E13 #define AB8500_IT_SOURCE20_REG 0x13
#define AB8500_IT_SOURCE21_REG 0x0E14 #define AB8500_IT_SOURCE21_REG 0x14
#define AB8500_IT_SOURCE22_REG 0x0E15 #define AB8500_IT_SOURCE22_REG 0x15
#define AB8500_IT_SOURCE23_REG 0x0E16 #define AB8500_IT_SOURCE23_REG 0x16
#define AB8500_IT_SOURCE24_REG 0x0E17 #define AB8500_IT_SOURCE24_REG 0x17
/* /*
* latch registers * latch registers
*/ */
#define AB8500_IT_LATCH1_REG 0x0E20 #define AB8500_IT_LATCH1_REG 0x20
#define AB8500_IT_LATCH2_REG 0x0E21 #define AB8500_IT_LATCH2_REG 0x21
#define AB8500_IT_LATCH3_REG 0x0E22 #define AB8500_IT_LATCH3_REG 0x22
#define AB8500_IT_LATCH4_REG 0x0E23 #define AB8500_IT_LATCH4_REG 0x23
#define AB8500_IT_LATCH5_REG 0x0E24 #define AB8500_IT_LATCH5_REG 0x24
#define AB8500_IT_LATCH6_REG 0x0E25 #define AB8500_IT_LATCH6_REG 0x25
#define AB8500_IT_LATCH7_REG 0x0E26 #define AB8500_IT_LATCH7_REG 0x26
#define AB8500_IT_LATCH8_REG 0x0E27 #define AB8500_IT_LATCH8_REG 0x27
#define AB8500_IT_LATCH9_REG 0x0E28 #define AB8500_IT_LATCH9_REG 0x28
#define AB8500_IT_LATCH10_REG 0x0E29 #define AB8500_IT_LATCH10_REG 0x29
#define AB8500_IT_LATCH19_REG 0x0E32 #define AB8500_IT_LATCH19_REG 0x32
#define AB8500_IT_LATCH20_REG 0x0E33 #define AB8500_IT_LATCH20_REG 0x33
#define AB8500_IT_LATCH21_REG 0x0E34 #define AB8500_IT_LATCH21_REG 0x34
#define AB8500_IT_LATCH22_REG 0x0E35 #define AB8500_IT_LATCH22_REG 0x35
#define AB8500_IT_LATCH23_REG 0x0E36 #define AB8500_IT_LATCH23_REG 0x36
#define AB8500_IT_LATCH24_REG 0x0E37 #define AB8500_IT_LATCH24_REG 0x37
/* /*
* mask registers * mask registers
*/ */
#define AB8500_IT_MASK1_REG 0x0E40 #define AB8500_IT_MASK1_REG 0x40
#define AB8500_IT_MASK2_REG 0x0E41 #define AB8500_IT_MASK2_REG 0x41
#define AB8500_IT_MASK3_REG 0x0E42 #define AB8500_IT_MASK3_REG 0x42
#define AB8500_IT_MASK4_REG 0x0E43 #define AB8500_IT_MASK4_REG 0x43
#define AB8500_IT_MASK5_REG 0x0E44 #define AB8500_IT_MASK5_REG 0x44
#define AB8500_IT_MASK6_REG 0x0E45 #define AB8500_IT_MASK6_REG 0x45
#define AB8500_IT_MASK7_REG 0x0E46 #define AB8500_IT_MASK7_REG 0x46
#define AB8500_IT_MASK8_REG 0x0E47 #define AB8500_IT_MASK8_REG 0x47
#define AB8500_IT_MASK9_REG 0x0E48 #define AB8500_IT_MASK9_REG 0x48
#define AB8500_IT_MASK10_REG 0x0E49 #define AB8500_IT_MASK10_REG 0x49
#define AB8500_IT_MASK11_REG 0x0E4A #define AB8500_IT_MASK11_REG 0x4A
#define AB8500_IT_MASK12_REG 0x0E4B #define AB8500_IT_MASK12_REG 0x4B
#define AB8500_IT_MASK13_REG 0x0E4C #define AB8500_IT_MASK13_REG 0x4C
#define AB8500_IT_MASK14_REG 0x0E4D #define AB8500_IT_MASK14_REG 0x4D
#define AB8500_IT_MASK15_REG 0x0E4E #define AB8500_IT_MASK15_REG 0x4E
#define AB8500_IT_MASK16_REG 0x0E4F #define AB8500_IT_MASK16_REG 0x4F
#define AB8500_IT_MASK17_REG 0x0E50 #define AB8500_IT_MASK17_REG 0x50
#define AB8500_IT_MASK18_REG 0x0E51 #define AB8500_IT_MASK18_REG 0x51
#define AB8500_IT_MASK19_REG 0x0E52 #define AB8500_IT_MASK19_REG 0x52
#define AB8500_IT_MASK20_REG 0x0E53 #define AB8500_IT_MASK20_REG 0x53
#define AB8500_IT_MASK21_REG 0x0E54 #define AB8500_IT_MASK21_REG 0x54
#define AB8500_IT_MASK22_REG 0x0E55 #define AB8500_IT_MASK22_REG 0x55
#define AB8500_IT_MASK23_REG 0x0E56 #define AB8500_IT_MASK23_REG 0x56
#define AB8500_IT_MASK24_REG 0x0E57 #define AB8500_IT_MASK24_REG 0x57
#define AB8500_REV_REG 0x1080 #define AB8500_REV_REG 0x80
/* /*
* Map interrupt numbers to the LATCH and MASK register offsets, Interrupt * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
...@@ -99,96 +101,132 @@ static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { ...@@ -99,96 +101,132 @@ static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = {
0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21,
}; };
static int __ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data) static int ab8500_get_chip_id(struct device *dev)
{
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
return (int)ab8500->chip_id;
}
static int set_register_interruptible(struct ab8500 *ab8500, u8 bank,
u8 reg, u8 data)
{ {
int ret; int ret;
/*
* Put the u8 bank and u8 register together into a an u16.
* The bank on higher 8 bits and register in lower 8 bits.
* */
u16 addr = ((u16)bank) << 8 | reg;
dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data); dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data);
ret = mutex_lock_interruptible(&ab8500->lock);
if (ret)
return ret;
ret = ab8500->write(ab8500, addr, data); ret = ab8500->write(ab8500, addr, data);
if (ret < 0) if (ret < 0)
dev_err(ab8500->dev, "failed to write reg %#x: %d\n", dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
addr, ret); addr, ret);
mutex_unlock(&ab8500->lock);
return ret; return ret;
} }
/** static int ab8500_set_register(struct device *dev, u8 bank,
* ab8500_write() - write an AB8500 register u8 reg, u8 value)
* @ab8500: device to write to
* @addr: address of the register
* @data: value to write
*/
int ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data)
{ {
int ret; struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
mutex_lock(&ab8500->lock);
ret = __ab8500_write(ab8500, addr, data);
mutex_unlock(&ab8500->lock);
return ret; return set_register_interruptible(ab8500, bank, reg, value);
} }
EXPORT_SYMBOL_GPL(ab8500_write);
static int __ab8500_read(struct ab8500 *ab8500, u16 addr) static int get_register_interruptible(struct ab8500 *ab8500, u8 bank,
u8 reg, u8 *value)
{ {
int ret; int ret;
/* put the u8 bank and u8 reg together into a an u16.
* bank on higher 8 bits and reg in lower */
u16 addr = ((u16)bank) << 8 | reg;
ret = mutex_lock_interruptible(&ab8500->lock);
if (ret)
return ret;
ret = ab8500->read(ab8500, addr); ret = ab8500->read(ab8500, addr);
if (ret < 0) if (ret < 0)
dev_err(ab8500->dev, "failed to read reg %#x: %d\n", dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
addr, ret); addr, ret);
else
*value = ret;
mutex_unlock(&ab8500->lock);
dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret); dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret);
return ret; return ret;
} }
/** static int ab8500_get_register(struct device *dev, u8 bank,
* ab8500_read() - read an AB8500 register u8 reg, u8 *value)
* @ab8500: device to read from
* @addr: address of the register
*/
int ab8500_read(struct ab8500 *ab8500, u16 addr)
{ {
int ret; struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
mutex_lock(&ab8500->lock);
ret = __ab8500_read(ab8500, addr);
mutex_unlock(&ab8500->lock);
return ret; return get_register_interruptible(ab8500, bank, reg, value);
} }
EXPORT_SYMBOL_GPL(ab8500_read);
static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
/** u8 reg, u8 bitmask, u8 bitvalues)
* ab8500_set_bits() - set a bitfield in an AB8500 register
* @ab8500: device to read from
* @addr: address of the register
* @mask: mask of the bitfield to modify
* @data: value to set to the bitfield
*/
int ab8500_set_bits(struct ab8500 *ab8500, u16 addr, u8 mask, u8 data)
{ {
int ret; int ret;
u8 data;
/* put the u8 bank and u8 reg together into a an u16.
* bank on higher 8 bits and reg in lower */
u16 addr = ((u16)bank) << 8 | reg;
mutex_lock(&ab8500->lock); ret = mutex_lock_interruptible(&ab8500->lock);
if (ret)
return ret;
ret = __ab8500_read(ab8500, addr); ret = ab8500->read(ab8500, addr);
if (ret < 0) if (ret < 0) {
dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
addr, ret);
goto out; goto out;
}
ret &= ~mask; data = (u8)ret;
ret |= data; data = (~bitmask & data) | (bitmask & bitvalues);
ret = __ab8500_write(ab8500, addr, ret); ret = ab8500->write(ab8500, addr, data);
if (ret < 0)
dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
addr, ret);
dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr, data);
out: out:
mutex_unlock(&ab8500->lock); mutex_unlock(&ab8500->lock);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(ab8500_set_bits);
static int ab8500_mask_and_set_register(struct device *dev,
u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
{
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
return mask_and_set_register_interruptible(ab8500, bank, reg,
bitmask, bitvalues);
}
static struct abx500_ops ab8500_ops = {
.get_chip_id = ab8500_get_chip_id,
.get_register = ab8500_get_register,
.set_register = ab8500_set_register,
.get_register_page = NULL,
.set_register_page = NULL,
.mask_and_set_register = ab8500_mask_and_set_register,
.event_registers_startup_state_get = NULL,
.startup_irq_enabled = NULL,
};
static void ab8500_irq_lock(unsigned int irq) static void ab8500_irq_lock(unsigned int irq)
{ {
...@@ -213,7 +251,7 @@ static void ab8500_irq_sync_unlock(unsigned int irq) ...@@ -213,7 +251,7 @@ static void ab8500_irq_sync_unlock(unsigned int irq)
ab8500->oldmask[i] = new; ab8500->oldmask[i] = new;
reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i];
ab8500_write(ab8500, reg, new); set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new);
} }
mutex_unlock(&ab8500->irq_lock); mutex_unlock(&ab8500->irq_lock);
...@@ -257,9 +295,11 @@ static irqreturn_t ab8500_irq(int irq, void *dev) ...@@ -257,9 +295,11 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
int regoffset = ab8500_irq_regoffset[i]; int regoffset = ab8500_irq_regoffset[i];
int status; int status;
u8 value;
status = ab8500_read(ab8500, AB8500_IT_LATCH1_REG + regoffset); status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
if (status <= 0) AB8500_IT_LATCH1_REG + regoffset, &value);
if (status < 0 || value == 0)
continue; continue;
do { do {
...@@ -267,8 +307,8 @@ static irqreturn_t ab8500_irq(int irq, void *dev) ...@@ -267,8 +307,8 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
int line = i * 8 + bit; int line = i * 8 + bit;
handle_nested_irq(ab8500->irq_base + line); handle_nested_irq(ab8500->irq_base + line);
status &= ~(1 << bit); value &= ~(1 << bit);
} while (status); } while (value);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -381,6 +421,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500) ...@@ -381,6 +421,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev);
int ret; int ret;
int i; int i;
u8 value;
if (plat) if (plat)
ab8500->irq_base = plat->irq_base; ab8500->irq_base = plat->irq_base;
...@@ -388,7 +429,8 @@ int __devinit ab8500_init(struct ab8500 *ab8500) ...@@ -388,7 +429,8 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
mutex_init(&ab8500->lock); mutex_init(&ab8500->lock);
mutex_init(&ab8500->irq_lock); mutex_init(&ab8500->irq_lock);
ret = ab8500_read(ab8500, AB8500_REV_REG); ret = get_register_interruptible(ab8500, AB8500_MISC,
AB8500_REV_REG, &value);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -397,28 +439,37 @@ int __devinit ab8500_init(struct ab8500 *ab8500) ...@@ -397,28 +439,37 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
* 0x10 - Cut 1.0 * 0x10 - Cut 1.0
* 0x11 - Cut 1.1 * 0x11 - Cut 1.1
*/ */
if (ret == 0x0 || ret == 0x10 || ret == 0x11) { if (value == 0x0 || value == 0x10 || value == 0x11) {
ab8500->revision = ret; ab8500->revision = value;
dev_info(ab8500->dev, "detected chip, revision: %#x\n", ret); dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
} else { } else {
dev_err(ab8500->dev, "unknown chip, revision: %#x\n", ret); dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
return -EINVAL; return -EINVAL;
} }
ab8500->chip_id = value;
if (plat && plat->init) if (plat && plat->init)
plat->init(ab8500); plat->init(ab8500);
/* Clear and mask all interrupts */ /* Clear and mask all interrupts */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); get_register_interruptible(ab8500, AB8500_INTERRUPT,
ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); AB8500_IT_LATCH1_REG + i, &value);
set_register_interruptible(ab8500, AB8500_INTERRUPT,
AB8500_IT_MASK1_REG + i, 0xff);
} }
for (i = 18; i < 24; i++) { for (i = 18; i < 24; i++) {
ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); get_register_interruptible(ab8500, AB8500_INTERRUPT,
ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); AB8500_IT_LATCH1_REG + i, &value);
set_register_interruptible(ab8500, AB8500_INTERRUPT,
AB8500_IT_MASK1_REG + i, 0xff);
} }
ret = abx500_register_ops(ab8500->dev, &ab8500_ops);
if (ret)
return ret;
for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) for (i = 0; i < AB8500_NUM_IRQ_REGS; i++)
ab8500->mask[i] = ab8500->oldmask[i] = 0xff; ab8500->mask[i] = ab8500->oldmask[i] = 0xff;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/ab8500.h> #include <linux/mfd/ab8500.h>
#include <linux/mfd/abx500.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/ab8500.h> #include <linux/regulator/ab8500.h>
...@@ -33,9 +34,11 @@ ...@@ -33,9 +34,11 @@
* @max_uV: maximum voltage (for variable voltage supplies) * @max_uV: maximum voltage (for variable voltage supplies)
* @min_uV: minimum voltage (for variable voltage supplies) * @min_uV: minimum voltage (for variable voltage supplies)
* @fixed_uV: typical voltage (for fixed voltage supplies) * @fixed_uV: typical voltage (for fixed voltage supplies)
* @update_bank: bank to control on/off
* @update_reg: register to control on/off * @update_reg: register to control on/off
* @mask: mask to enable/disable regulator * @mask: mask to enable/disable regulator
* @enable: bits to enable the regulator in normal(high power) mode * @enable: bits to enable the regulator in normal(high power) mode
* @voltage_bank: bank to control regulator voltage
* @voltage_reg: register to control regulator voltage * @voltage_reg: register to control regulator voltage
* @voltage_mask: mask to control regulator voltage * @voltage_mask: mask to control regulator voltage
* @supported_voltages: supported voltage table * @supported_voltages: supported voltage table
...@@ -49,11 +52,13 @@ struct ab8500_regulator_info { ...@@ -49,11 +52,13 @@ struct ab8500_regulator_info {
int max_uV; int max_uV;
int min_uV; int min_uV;
int fixed_uV; int fixed_uV;
int update_reg; u8 update_bank;
int mask; u8 update_reg;
int enable; u8 mask;
int voltage_reg; u8 enable;
int voltage_mask; u8 voltage_bank;
u8 voltage_reg;
u8 voltage_mask;
int const *supported_voltages; int const *supported_voltages;
int voltages_len; int voltages_len;
}; };
...@@ -97,8 +102,8 @@ static int ab8500_regulator_enable(struct regulator_dev *rdev) ...@@ -97,8 +102,8 @@ static int ab8500_regulator_enable(struct regulator_dev *rdev)
if (regulator_id >= AB8500_NUM_REGULATORS) if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL; return -EINVAL;
ret = ab8500_set_bits(info->ab8500, info->update_reg, ret = abx500_mask_and_set_register_interruptible(info->dev,
info->mask, info->enable); info->update_bank, info->update_reg, info->mask, info->enable);
if (ret < 0) if (ret < 0)
dev_err(rdev_get_dev(rdev), dev_err(rdev_get_dev(rdev),
"couldn't set enable bits for regulator\n"); "couldn't set enable bits for regulator\n");
...@@ -114,8 +119,8 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev) ...@@ -114,8 +119,8 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev)
if (regulator_id >= AB8500_NUM_REGULATORS) if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL; return -EINVAL;
ret = ab8500_set_bits(info->ab8500, info->update_reg, ret = abx500_mask_and_set_register_interruptible(info->dev,
info->mask, 0x0); info->update_bank, info->update_reg, info->mask, 0x0);
if (ret < 0) if (ret < 0)
dev_err(rdev_get_dev(rdev), dev_err(rdev_get_dev(rdev),
"couldn't set disable bits for regulator\n"); "couldn't set disable bits for regulator\n");
...@@ -126,19 +131,21 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) ...@@ -126,19 +131,21 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
{ {
int regulator_id, ret; int regulator_id, ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
u8 value;
regulator_id = rdev_get_id(rdev); regulator_id = rdev_get_id(rdev);
if (regulator_id >= AB8500_NUM_REGULATORS) if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL; return -EINVAL;
ret = ab8500_read(info->ab8500, info->update_reg); ret = abx500_get_register_interruptible(info->dev,
info->update_bank, info->update_reg, &value);
if (ret < 0) { if (ret < 0) {
dev_err(rdev_get_dev(rdev), dev_err(rdev_get_dev(rdev),
"couldn't read 0x%x register\n", info->update_reg); "couldn't read 0x%x register\n", info->update_reg);
return ret; return ret;
} }
if (ret & info->mask) if (value & info->mask)
return true; return true;
else else
return false; return false;
...@@ -165,14 +172,16 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) ...@@ -165,14 +172,16 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector)
static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) static int ab8500_regulator_get_voltage(struct regulator_dev *rdev)
{ {
int regulator_id, ret, val; int regulator_id, ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
u8 value;
regulator_id = rdev_get_id(rdev); regulator_id = rdev_get_id(rdev);
if (regulator_id >= AB8500_NUM_REGULATORS) if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL; return -EINVAL;
ret = ab8500_read(info->ab8500, info->voltage_reg); ret = abx500_get_register_interruptible(info->dev, info->voltage_bank,
info->voltage_reg, &value);
if (ret < 0) { if (ret < 0) {
dev_err(rdev_get_dev(rdev), dev_err(rdev_get_dev(rdev),
"couldn't read voltage reg for regulator\n"); "couldn't read voltage reg for regulator\n");
...@@ -180,11 +189,11 @@ static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) ...@@ -180,11 +189,11 @@ static int ab8500_regulator_get_voltage(struct regulator_dev *rdev)
} }
/* vintcore has a different layout */ /* vintcore has a different layout */
val = ret & info->voltage_mask; value &= info->voltage_mask;
if (regulator_id == AB8500_LDO_INTCORE) if (regulator_id == AB8500_LDO_INTCORE)
ret = info->supported_voltages[val >> 0x3]; ret = info->supported_voltages[value >> 0x3];
else else
ret = info->supported_voltages[val]; ret = info->supported_voltages[value];
return ret; return ret;
} }
...@@ -224,8 +233,9 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -224,8 +233,9 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
} }
/* set the registers for the request */ /* set the registers for the request */
ret = ab8500_set_bits(info->ab8500, info->voltage_reg, ret = abx500_mask_and_set_register_interruptible(info->dev,
info->voltage_mask, ret); info->voltage_bank, info->voltage_reg,
info->voltage_mask, (u8)ret);
if (ret < 0) if (ret < 0)
dev_err(rdev_get_dev(rdev), dev_err(rdev_get_dev(rdev),
"couldn't set voltage reg for regulator\n"); "couldn't set voltage reg for regulator\n");
...@@ -262,9 +272,9 @@ static struct regulator_ops ab8500_ldo_fixed_ops = { ...@@ -262,9 +272,9 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
.list_voltage = ab8500_list_voltage, .list_voltage = ab8500_list_voltage,
}; };
#define AB8500_LDO(_id, min, max, reg, reg_mask, reg_enable, \ #define AB8500_LDO(_id, min, max, bank, reg, reg_mask, \
volt_reg, volt_mask, voltages, \ reg_enable, volt_bank, volt_reg, volt_mask, \
len_volts) \ voltages, len_volts) \
{ \ { \
.desc = { \ .desc = { \
.name = "LDO-" #_id, \ .name = "LDO-" #_id, \
...@@ -275,9 +285,11 @@ static struct regulator_ops ab8500_ldo_fixed_ops = { ...@@ -275,9 +285,11 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
}, \ }, \
.min_uV = (min) * 1000, \ .min_uV = (min) * 1000, \
.max_uV = (max) * 1000, \ .max_uV = (max) * 1000, \
.update_bank = bank, \
.update_reg = reg, \ .update_reg = reg, \
.mask = reg_mask, \ .mask = reg_mask, \
.enable = reg_enable, \ .enable = reg_enable, \
.voltage_bank = volt_bank, \
.voltage_reg = volt_reg, \ .voltage_reg = volt_reg, \
.voltage_mask = volt_mask, \ .voltage_mask = volt_mask, \
.supported_voltages = voltages, \ .supported_voltages = voltages, \
...@@ -285,8 +297,8 @@ static struct regulator_ops ab8500_ldo_fixed_ops = { ...@@ -285,8 +297,8 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
.fixed_uV = 0, \ .fixed_uV = 0, \
} }
#define AB8500_FIXED_LDO(_id, fixed, reg, reg_mask, \ #define AB8500_FIXED_LDO(_id, fixed, bank, reg, \
reg_enable) \ reg_mask, reg_enable) \
{ \ { \
.desc = { \ .desc = { \
.name = "LDO-" #_id, \ .name = "LDO-" #_id, \
...@@ -296,6 +308,7 @@ static struct regulator_ops ab8500_ldo_fixed_ops = { ...@@ -296,6 +308,7 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
}, \ }, \
.fixed_uV = fixed * 1000, \ .fixed_uV = fixed * 1000, \
.update_bank = bank, \
.update_reg = reg, \ .update_reg = reg, \
.mask = reg_mask, \ .mask = reg_mask, \
.enable = reg_enable, \ .enable = reg_enable, \
...@@ -304,28 +317,29 @@ static struct regulator_ops ab8500_ldo_fixed_ops = { ...@@ -304,28 +317,29 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
static struct ab8500_regulator_info ab8500_regulator_info[] = { static struct ab8500_regulator_info ab8500_regulator_info[] = {
/* /*
* Variable Voltage LDOs * Variable Voltage LDOs
* name, min uV, max uV, ctrl reg, reg mask, enable mask, * name, min uV, max uV, ctrl bank, ctrl reg, reg mask, enable mask,
* volt ctrl reg, volt ctrl mask, volt table, num supported volts * volt ctrl bank, volt ctrl reg, volt ctrl mask, volt table,
* num supported volts
*/ */
AB8500_LDO(AUX1, 1100, 3300, 0x0409, 0x3, 0x1, 0x041f, 0xf, AB8500_LDO(AUX1, 1100, 3300, 0x04, 0x09, 0x3, 0x1, 0x04, 0x1f, 0xf,
ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)),
AB8500_LDO(AUX2, 1100, 3300, 0x0409, 0xc, 0x4, 0x0420, 0xf, AB8500_LDO(AUX2, 1100, 3300, 0x04, 0x09, 0xc, 0x4, 0x04, 0x20, 0xf,
ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)),
AB8500_LDO(AUX3, 1100, 3300, 0x040a, 0x3, 0x1, 0x0421, 0xf, AB8500_LDO(AUX3, 1100, 3300, 0x04, 0x0a, 0x3, 0x1, 0x04, 0x21, 0xf,
ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)),
AB8500_LDO(INTCORE, 1100, 3300, 0x0380, 0x4, 0x4, 0x0380, 0x38, AB8500_LDO(INTCORE, 1100, 3300, 0x03, 0x80, 0x4, 0x4, 0x03, 0x80, 0x38,
ldo_vintcore_voltages, ARRAY_SIZE(ldo_vintcore_voltages)), ldo_vintcore_voltages, ARRAY_SIZE(ldo_vintcore_voltages)),
/* /*
* Fixed Voltage LDOs * Fixed Voltage LDOs
* name, o/p uV, ctrl reg, enable, disable * name, o/p uV, ctrl bank, ctrl reg, enable, disable
*/ */
AB8500_FIXED_LDO(TVOUT, 2000, 0x0380, 0x2, 0x2), AB8500_FIXED_LDO(TVOUT, 2000, 0x03, 0x80, 0x2, 0x2),
AB8500_FIXED_LDO(AUDIO, 2000, 0x0383, 0x2, 0x2), AB8500_FIXED_LDO(AUDIO, 2000, 0x03, 0x83, 0x2, 0x2),
AB8500_FIXED_LDO(ANAMIC1, 2050, 0x0383, 0x4, 0x4), AB8500_FIXED_LDO(ANAMIC1, 2050, 0x03, 0x83, 0x4, 0x4),
AB8500_FIXED_LDO(ANAMIC2, 2050, 0x0383, 0x8, 0x8), AB8500_FIXED_LDO(ANAMIC2, 2050, 0x03, 0x83, 0x8, 0x8),
AB8500_FIXED_LDO(DMIC, 1800, 0x0383, 0x10, 0x10), AB8500_FIXED_LDO(DMIC, 1800, 0x03, 0x83, 0x10, 0x10),
AB8500_FIXED_LDO(ANA, 1200, 0x0383, 0xc, 0x4), AB8500_FIXED_LDO(ANA, 1200, 0x03, 0x83, 0xc, 0x4),
}; };
static inline struct ab8500_regulator_info *find_regulator_info(int id) static inline struct ab8500_regulator_info *find_regulator_info(int id)
......
...@@ -14,26 +14,26 @@ ...@@ -14,26 +14,26 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/ab8500.h> #include <linux/mfd/ab8500.h>
#include <linux/delay.h> #include <linux/delay.h>
#define AB8500_RTC_SOFF_STAT_REG 0x0F00 #define AB8500_RTC_SOFF_STAT_REG 0x00
#define AB8500_RTC_CC_CONF_REG 0x0F01 #define AB8500_RTC_CC_CONF_REG 0x01
#define AB8500_RTC_READ_REQ_REG 0x0F02 #define AB8500_RTC_READ_REQ_REG 0x02
#define AB8500_RTC_WATCH_TSECMID_REG 0x0F03 #define AB8500_RTC_WATCH_TSECMID_REG 0x03
#define AB8500_RTC_WATCH_TSECHI_REG 0x0F04 #define AB8500_RTC_WATCH_TSECHI_REG 0x04
#define AB8500_RTC_WATCH_TMIN_LOW_REG 0x0F05 #define AB8500_RTC_WATCH_TMIN_LOW_REG 0x05
#define AB8500_RTC_WATCH_TMIN_MID_REG 0x0F06 #define AB8500_RTC_WATCH_TMIN_MID_REG 0x06
#define AB8500_RTC_WATCH_TMIN_HI_REG 0x0F07 #define AB8500_RTC_WATCH_TMIN_HI_REG 0x07
#define AB8500_RTC_ALRM_MIN_LOW_REG 0x0F08 #define AB8500_RTC_ALRM_MIN_LOW_REG 0x08
#define AB8500_RTC_ALRM_MIN_MID_REG 0x0F09 #define AB8500_RTC_ALRM_MIN_MID_REG 0x09
#define AB8500_RTC_ALRM_MIN_HI_REG 0x0F0A #define AB8500_RTC_ALRM_MIN_HI_REG 0x0A
#define AB8500_RTC_STAT_REG 0x0F0B #define AB8500_RTC_STAT_REG 0x0B
#define AB8500_RTC_BKUP_CHG_REG 0x0F0C #define AB8500_RTC_BKUP_CHG_REG 0x0C
#define AB8500_RTC_FORCE_BKUP_REG 0x0F0D #define AB8500_RTC_FORCE_BKUP_REG 0x0D
#define AB8500_RTC_CALIB_REG 0x0F0E #define AB8500_RTC_CALIB_REG 0x0E
#define AB8500_RTC_SWITCH_STAT_REG 0x0F0F #define AB8500_RTC_SWITCH_STAT_REG 0x0F
#define AB8500_REV_REG 0x1080
/* RtcReadRequest bits */ /* RtcReadRequest bits */
#define RTC_READ_REQUEST 0x01 #define RTC_READ_REQUEST 0x01
...@@ -46,13 +46,13 @@ ...@@ -46,13 +46,13 @@
#define COUNTS_PER_SEC (0xF000 / 60) #define COUNTS_PER_SEC (0xF000 / 60)
#define AB8500_RTC_EPOCH 2000 #define AB8500_RTC_EPOCH 2000
static const unsigned long ab8500_rtc_time_regs[] = { static const u8 ab8500_rtc_time_regs[] = {
AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG,
AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG, AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG,
AB8500_RTC_WATCH_TSECMID_REG AB8500_RTC_WATCH_TSECMID_REG
}; };
static const unsigned long ab8500_rtc_alarm_regs[] = { static const u8 ab8500_rtc_alarm_regs[] = {
AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG, AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG,
AB8500_RTC_ALRM_MIN_LOW_REG AB8500_RTC_ALRM_MIN_LOW_REG
}; };
...@@ -76,29 +76,30 @@ static unsigned long get_elapsed_seconds(int year) ...@@ -76,29 +76,30 @@ static unsigned long get_elapsed_seconds(int year)
static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
unsigned long timeout = jiffies + HZ; unsigned long timeout = jiffies + HZ;
int retval, i; int retval, i;
unsigned long mins, secs; unsigned long mins, secs;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
u8 value;
/* Request a data read */ /* Request a data read */
retval = ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, retval = abx500_set_register_interruptible(dev,
RTC_READ_REQUEST); AB8500_RTC, AB8500_RTC_READ_REQ_REG, RTC_READ_REQUEST);
if (retval < 0) if (retval < 0)
return retval; return retval;
/* Early AB8500 chips will not clear the rtc read request bit */ /* Early AB8500 chips will not clear the rtc read request bit */
if (ab8500->revision == 0) { if (abx500_get_chip_id(dev) == 0) {
msleep(1); msleep(1);
} else { } else {
/* Wait for some cycles after enabling the rtc read in ab8500 */ /* Wait for some cycles after enabling the rtc read in ab8500 */
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
retval = ab8500_read(ab8500, AB8500_RTC_READ_REQ_REG); retval = abx500_get_register_interruptible(dev,
AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value);
if (retval < 0) if (retval < 0)
return retval; return retval;
if (!(retval & RTC_READ_REQUEST)) if (!(value & RTC_READ_REQUEST))
break; break;
msleep(1); msleep(1);
...@@ -107,10 +108,11 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -107,10 +108,11 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* Read the Watchtime registers */ /* Read the Watchtime registers */
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) {
retval = ab8500_read(ab8500, ab8500_rtc_time_regs[i]); retval = abx500_get_register_interruptible(dev,
AB8500_RTC, ab8500_rtc_time_regs[i], &value);
if (retval < 0) if (retval < 0)
return retval; return retval;
buf[i] = retval; buf[i] = value;
} }
mins = (buf[0] << 16) | (buf[1] << 8) | buf[2]; mins = (buf[0] << 16) | (buf[1] << 8) | buf[2];
...@@ -128,7 +130,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -128,7 +130,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
int retval, i; int retval, i;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
unsigned long no_secs, no_mins, secs = 0; unsigned long no_secs, no_mins, secs = 0;
...@@ -162,27 +163,29 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -162,27 +163,29 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[0] = (no_mins >> 16) & 0xFF; buf[0] = (no_mins >> 16) & 0xFF;
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) {
retval = ab8500_write(ab8500, ab8500_rtc_time_regs[i], buf[i]); retval = abx500_set_register_interruptible(dev, AB8500_RTC,
ab8500_rtc_time_regs[i], buf[i]);
if (retval < 0) if (retval < 0)
return retval; return retval;
} }
/* Request a data write */ /* Request a data write */
return ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST); return abx500_set_register_interruptible(dev, AB8500_RTC,
AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST);
} }
static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
int retval, i; int retval, i;
int rtc_ctrl; u8 rtc_ctrl, value;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
unsigned long secs, mins; unsigned long secs, mins;
/* Check if the alarm is enabled or not */ /* Check if the alarm is enabled or not */
rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); retval = abx500_get_register_interruptible(dev, AB8500_RTC,
if (rtc_ctrl < 0) AB8500_RTC_STAT_REG, &rtc_ctrl);
return rtc_ctrl; if (retval < 0)
return retval;
if (rtc_ctrl & RTC_ALARM_ENA) if (rtc_ctrl & RTC_ALARM_ENA)
alarm->enabled = 1; alarm->enabled = 1;
...@@ -192,10 +195,11 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -192,10 +195,11 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
alarm->pending = 0; alarm->pending = 0;
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) {
retval = ab8500_read(ab8500, ab8500_rtc_alarm_regs[i]); retval = abx500_get_register_interruptible(dev, AB8500_RTC,
ab8500_rtc_alarm_regs[i], &value);
if (retval < 0) if (retval < 0)
return retval; return retval;
buf[i] = retval; buf[i] = value;
} }
mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
...@@ -211,15 +215,13 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -211,15 +215,13 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled) static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); return abx500_mask_and_set_register_interruptible(dev, AB8500_RTC,
AB8500_RTC_STAT_REG, RTC_ALARM_ENA,
return ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_ALARM_ENA,
enabled ? RTC_ALARM_ENA : 0); enabled ? RTC_ALARM_ENA : 0);
} }
static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
int retval, i; int retval, i;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
unsigned long mins, secs = 0; unsigned long mins, secs = 0;
...@@ -247,7 +249,8 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -247,7 +249,8 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
/* Set the alarm time */ /* Set the alarm time */
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) {
retval = ab8500_write(ab8500, ab8500_rtc_alarm_regs[i], buf[i]); retval = abx500_set_register_interruptible(dev, AB8500_RTC,
ab8500_rtc_alarm_regs[i], buf[i]);
if (retval < 0) if (retval < 0)
return retval; return retval;
} }
...@@ -276,10 +279,9 @@ static const struct rtc_class_ops ab8500_rtc_ops = { ...@@ -276,10 +279,9 @@ static const struct rtc_class_ops ab8500_rtc_ops = {
static int __devinit ab8500_rtc_probe(struct platform_device *pdev) static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
int err; int err;
struct rtc_device *rtc; struct rtc_device *rtc;
int rtc_ctrl; u8 rtc_ctrl;
int irq; int irq;
irq = platform_get_irq_byname(pdev, "ALARM"); irq = platform_get_irq_byname(pdev, "ALARM");
...@@ -287,17 +289,18 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev) ...@@ -287,17 +289,18 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
return irq; return irq;
/* For RTC supply test */ /* For RTC supply test */
err = ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_STATUS_DATA, err = abx500_mask_and_set_register_interruptible(&pdev->dev, AB8500_RTC,
RTC_STATUS_DATA); AB8500_RTC_STAT_REG, RTC_STATUS_DATA, RTC_STATUS_DATA);
if (err < 0) if (err < 0)
return err; return err;
/* Wait for reset by the PorRtc */ /* Wait for reset by the PorRtc */
msleep(1); msleep(1);
rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC,
if (rtc_ctrl < 0) AB8500_RTC_STAT_REG, &rtc_ctrl);
return rtc_ctrl; if (err < 0)
return err;
/* Check if the RTC Supply fails */ /* Check if the RTC Supply fails */
if (!(rtc_ctrl & RTC_STATUS_DATA)) { if (!(rtc_ctrl & RTC_STATUS_DATA)) {
......
...@@ -9,6 +9,29 @@ ...@@ -9,6 +9,29 @@
#include <linux/device.h> #include <linux/device.h>
/*
* AB8500 bank addresses
*/
#define AB8500_SYS_CTRL1_BLOCK 0x1
#define AB8500_SYS_CTRL2_BLOCK 0x2
#define AB8500_REGU_CTRL1 0x3
#define AB8500_REGU_CTRL2 0x4
#define AB8500_USB 0x5
#define AB8500_TVOUT 0x6
#define AB8500_DBI 0x7
#define AB8500_ECI_AV_ACC 0x8
#define AB8500_RESERVED 0x9
#define AB8500_GPADC 0xA
#define AB8500_CHARGER 0xB
#define AB8500_GAS_GAUGE 0xC
#define AB8500_AUDIO 0xD
#define AB8500_INTERRUPT 0xE
#define AB8500_RTC 0xF
#define AB8500_MISC 0x10
#define AB8500_DEBUG 0x12
#define AB8500_PROD_TEST 0x13
#define AB8500_OTP_EMUL 0x15
/* /*
* Interrupts * Interrupts
*/ */
...@@ -99,6 +122,7 @@ struct ab8500 { ...@@ -99,6 +122,7 @@ struct ab8500 {
int revision; int revision;
int irq_base; int irq_base;
int irq; int irq;
u8 chip_id;
int (*write) (struct ab8500 *a8500, u16 addr, u8 data); int (*write) (struct ab8500 *a8500, u16 addr, u8 data);
int (*read) (struct ab8500 *a8500, u16 addr); int (*read) (struct ab8500 *a8500, u16 addr);
...@@ -124,10 +148,6 @@ struct ab8500_platform_data { ...@@ -124,10 +148,6 @@ struct ab8500_platform_data {
struct regulator_init_data *regulator[AB8500_NUM_REGULATORS]; struct regulator_init_data *regulator[AB8500_NUM_REGULATORS];
}; };
extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data);
extern int ab8500_read(struct ab8500 *a8500, u16 addr);
extern int ab8500_set_bits(struct ab8500 *a8500, u16 addr, u8 mask, u8 data);
extern int __devinit ab8500_init(struct ab8500 *ab8500); extern int __devinit ab8500_init(struct ab8500 *ab8500);
extern int __devexit ab8500_exit(struct ab8500 *ab8500); extern int __devexit ab8500_exit(struct ab8500 *ab8500);
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
* *
* ABX500 core access functions. * ABX500 core access functions.
* The abx500 interface is used for the Analog Baseband chip * The abx500 interface is used for the Analog Baseband chip
* ab3100, ab3550, ab5500 and possibly comming. It is not used for * ab3100, ab3550, ab5500, and ab8500.
* ab4500 and ab8500 since they are another family of chip.
* *
* Author: Mattias Wallin <mattias.wallin@stericsson.com> * Author: Mattias Wallin <mattias.wallin@stericsson.com>
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment