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
......
This diff is collapsed.
...@@ -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