aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gta02.h3
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c169
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_bt.c1
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_gps.c1
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_gsm.c2
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_host.c2
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c6
-rw-r--r--drivers/power/bq27000_battery.c97
-rw-r--r--drivers/regulator/pcf50633-regulator.c28
-rw-r--r--drivers/rtc/rtc-pcf50633.c147
-rw-r--r--include/linux/bq27000_battery.h2
-rw-r--r--include/linux/rtc/pcf50633.h13
12 files changed, 198 insertions, 273 deletions
diff --git a/arch/arm/mach-s3c2410/include/mach/gta02.h b/arch/arm/mach-s3c2410/include/mach/gta02.h
index 7f103bd2912..354043b8e2d 100644
--- a/arch/arm/mach-s3c2410/include/mach/gta02.h
+++ b/arch/arm/mach-s3c2410/include/mach/gta02.h
@@ -3,7 +3,8 @@
#include <mach/regs-gpio.h>
#include <mach/irqs.h>
-#include <linux/pcf50633.h>
+
+#include <linux/mfd/pcf50633/core.h>
/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
#define GTA02v1_SYSTEM_REV 0x00000310
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index 340f45753e6..6d9e432dde1 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -49,7 +49,12 @@
#include <linux/backlight.h>
#include <linux/regulator/machine.h>
-#include <linux/pcf50633.h>
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/led.h>
+
#include <linux/lis302dl.h>
#include <asm/mach/arch.h>
@@ -103,9 +108,6 @@
/* arbitrates which sensor IRQ owns the shared SPI bus */
static spinlock_t motion_irq_lock;
-static int gta02_charger_online_status;
-static int gta02_charger_active_status;
-
/* define FIQ IPC struct */
/*
* contains stuff FIQ ISR modifies and normal kernel code can see and use
@@ -472,12 +474,16 @@ static struct s3c2410_uartcfg gta02_uartcfgs[] = {
static int gta02_get_charger_online_status(void)
{
- return gta02_charger_online_status;
+ struct pcf50633 *pcf = gta02_pcf_pdata.pcf;
+
+ return pcf->mbc.usb_online;
}
static int gta02_get_charger_active_status(void)
{
- return gta02_charger_active_status;
+ struct pcf50633 *pcf = gta02_pcf_pdata.pcf;
+
+ return pcf->mbc.usb_active;
}
@@ -498,40 +504,65 @@ struct platform_device bq27000_battery_device = {
},
};
+#define ADC_NOM_CHG_DETECT_1A 6
+#define ADC_NOM_CHG_DETECT_USB 43
+
+static void
+gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
+{
+ int ma;
+
+ /* Interpret charger type */
+ if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
+
+ /* Stop GPO driving out now that we have a IA charger */
+ pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
+
+ ma = 1000;
+ pcf->mbc.usb_active = 1;
+ } else {
+ ma = 100;
+
+ /* We know that we can't charge now */
+ pcf->mbc.usb_active = 0;
+ }
+
+ pcf50633_mbc_usb_curlim_set(pcf, ma);
+}
-/* PMU driver info */
+static struct delayed_work gta02_charger_work;
+static int gta02_usb_vbus_draw;
-static int pmu_callback(struct device *dev, unsigned int feature,
- enum pmu_event event)
+static void gta02_charger_worker(struct work_struct *work)
{
- switch (feature) {
- case PCF50633_FEAT_MBC:
- switch (event) {
- case PMU_EVT_CHARGER_IDLE:
- gta02_charger_active_status = 0;
- break;
- case PMU_EVT_CHARGER_ACTIVE:
- gta02_charger_active_status = 1;
- break;
- case PMU_EVT_USB_INSERT:
- gta02_charger_online_status = 1;
- break;
- case PMU_EVT_USB_REMOVE:
- gta02_charger_online_status = 0;
- break;
- case PMU_EVT_INSERT: /* adapter is unsused */
- case PMU_EVT_REMOVE: /* adapter is unused */
- break;
- default:
- break;
- }
- break;
- default:
- break;
+ struct pcf50633 *pcf = gta02_pcf_pdata.pcf;
+
+ if (gta02_usb_vbus_draw) {
+ /* We can charge now */
+ pcf->mbc.usb_active = 1;
+
+ pcf50633_mbc_usb_curlim_set(pcf, gta02_usb_vbus_draw);
+ return;
+ } else {
+ pcf50633_adc_async_read(pcf,
+ PCF50633_ADCC1_MUX_ADCIN1,
+ PCF50633_ADCC1_AVERAGE_16,
+ gta02_configure_pmu_for_charger, NULL);
+ return;
}
+}
- bq27000_charging_state_change(&bq27000_battery_device);
- return 0;
+#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
+static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
+{
+ if (irq == PCF50633_IRQ_USBINS) {
+ schedule_delayed_work(&gta02_charger_work,
+ GTA02_CHARGER_CONFIGURE_TIMEOUT);
+ return;
+ } else if (irq == PCF50633_IRQ_USBREM) {
+ cancel_delayed_work_sync(&gta02_charger_work);
+ gta02_usb_vbus_draw = 0;
+ }
}
static struct platform_device gta01_pm_gps_dev = {
@@ -556,8 +587,8 @@ static struct platform_device gta02_pm_gsm_dev = {
static struct platform_device gta02_glamo_dev;
static void mangle_glamo_res_by_system_rev(void);
-static void gta02_pcf50633_attach_child_devices(struct device *parent_device);
-static void gta02_pcf50633_regulator_registered(struct pcf50633_data *pcf, int id);
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
+static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id);
static struct platform_device gta02_pm_wlan_dev = {
.name = "gta02-pm-wlan",
@@ -591,31 +622,25 @@ static struct regulator_consumer_supply hcldo_consumers[] = {
},
};
+static char *gta02_batteries[] = {
+ "battery",
+};
+
struct pcf50633_platform_data gta02_pcf_pdata = {
- .used_features = PCF50633_FEAT_MBC |
- PCF50633_FEAT_BBC |
- PCF50633_FEAT_RTC |
- PCF50633_FEAT_CHGCUR |
- PCF50633_FEAT_BATVOLT |
- PCF50633_FEAT_BATTEMP |
- PCF50633_FEAT_PWM_BL,
- .onkey_seconds_sig_init = 4,
- .onkey_seconds_shutdown = 8,
- .cb = &pmu_callback,
- .r_fix_batt = 10000,
- .r_fix_batt_par = 10000,
- .r_sense_milli = 220,
- .flag_use_apm_emulation = 0,
.resumers = {
- [0] = PCF50633_INT1_USBINS |
- PCF50633_INT1_USBREM |
- PCF50633_INT1_ALARM,
- [1] = PCF50633_INT2_ONKEYF,
- [2] = PCF50633_INT3_ONKEY1S
+ [0] = PCF50633_INT1_USBINS |
+ PCF50633_INT1_USBREM |
+ PCF50633_INT1_ALARM,
+ [1] = PCF50633_INT2_ONKEYF,
+ [2] = PCF50633_INT3_ONKEY1S,
+ [3] = PCF50633_INT4_LOWSYS |
+ PCF50633_INT4_LOWBAT |
+ PCF50633_INT4_HIGHTMP,
},
- /* warning: these get rewritten during machine init below
- * depending on pcb variant
- */
+
+ .batteries = gta02_batteries,
+ .num_batteries = ARRAY_SIZE(gta02_batteries),
+
.reg_init_data = {
[PCF50633_REGULATOR_AUTO] = {
.constraints = {
@@ -655,6 +680,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
.min_uV = 2000000,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_modes_mask = REGULATOR_CHANGE_VOLTAGE,
},
.num_consumer_supplies = 1,
.consumer_supplies = hcldo_consumers,
@@ -730,8 +756,9 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
},
},
- .attach_child_devices = gta02_pcf50633_attach_child_devices,
- .regulator_registered = gta02_pcf50633_regulator_registered,
+ .probe_done = gta02_pmu_attach_child_devices,
+ .regulator_registered = gta02_pmu_regulator_registered,
+ .mbc_event_callback = gta02_pmu_event_callback,
};
static void mangle_pmu_pdata_by_system_rev(void)
@@ -954,7 +981,7 @@ static void gta02_udc_vbus_draw(unsigned int ma)
if (!gta02_pcf_pdata.pcf)
return;
- pcf50633_notify_usb_current_limit_change(gta02_pcf_pdata.pcf, ma);
+ gta02_usb_vbus_draw = ma;
}
static struct s3c2410_udc_mach_info gta02_udc_cfg = {
@@ -995,7 +1022,7 @@ static struct s3c2410_ts_mach_info gta02_ts_cfg = {
static void gta02_bl_set_intensity(int intensity)
{
- struct pcf50633_data *pcf = gta02_pcf_pdata.pcf;
+ struct pcf50633 *pcf = gta02_pcf_pdata.pcf;
int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
int ret;
@@ -1553,11 +1580,11 @@ static struct platform_device *gta02_devices_pmu_children[] = {
&gta02_resume_reason_device,
};
-static void gta02_pcf50633_regulator_registered(struct pcf50633_data *pcf, int id)
+static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id)
{
struct platform_device *regulator, *pdev;
- regulator = pcf->regulator_pdev[id];
+ regulator = pcf->pmic.pdev[id];
switch(id) {
case PCF50633_REGULATOR_LDO4:
@@ -1584,16 +1611,22 @@ static void gta02_pcf50633_regulator_registered(struct pcf50633_data *pcf, int i
* the pcf50633 still around.
*/
-static void gta02_pcf50633_attach_child_devices(struct device *parent_device)
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
{
int n;
for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
- gta02_devices_pmu_children[n]->dev.parent = parent_device;
+ gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
mangle_glamo_res_by_system_rev();
platform_add_devices(gta02_devices_pmu_children,
ARRAY_SIZE(gta02_devices_pmu_children));
+
+ /* Switch on backlight. Qi does not do it for us */
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 0x01);
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x01);
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDOUT, 0x3f);
}
@@ -1662,6 +1695,8 @@ static void __init gta02_machine_init(void)
if (rc < 0)
printk(KERN_ERR "GTA02: can't request ar6k wakeup IRQ\n");
enable_irq_wake(GTA02_IRQ_WLAN_GPIO1);
+
+ INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
}
void DEBUG_LED(int n)
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
index 1e3d9698e78..d3a046cada1 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
@@ -27,7 +27,6 @@
/* For GTA02 */
#include <mach/gta02.h>
-#include <linux/pcf50633.h>
#include <linux/regulator/consumer.h>
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
index 1715769cbb1..89075693b9f 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
@@ -29,7 +29,6 @@
/* For GTA02 */
#include <mach/gta02.h>
-#include <linux/pcf50633.h>
#include <linux/regulator/consumer.h>
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
index ebed33558a7..46c99c9042f 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
@@ -29,7 +29,7 @@
/* For GTA02 */
#include <mach/gta02.h>
-#include <linux/pcf50633.h>
+#include <linux/mfd/pcf50633/gpio.h>
#include <mach/regs-gpio.h>
#include <mach/regs-gpioj.h>
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_host.c b/arch/arm/plat-s3c24xx/neo1973_pm_host.c
index 8ab589b3ad8..caa302eeb91 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_host.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_host.c
@@ -21,7 +21,7 @@
#ifdef CONFIG_MACH_NEO1973_GTA02
#include <mach/gta02.h>
-#include <linux/pcf50633.h>
+#include <linux/mfd/pcf50633/core.h>
static ssize_t pm_host_read(struct device *dev, struct device_attribute *attr,
char *buf)
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
index a04466c8960..62984a50a0a 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
@@ -22,7 +22,7 @@
#ifdef CONFIG_MACH_NEO1973_GTA02
#include <mach/gta02.h>
-#include <linux/pcf50633.h>
+#include <linux/mfd/pcf50633/core.h>
#endif
static unsigned int *gstatus4_mapped;
@@ -79,8 +79,8 @@ static ssize_t resume_reason_read(struct device *dev,
end += sprintf(end, " %s\n", resume_reasons[gta][bit]);
#ifdef CONFIG_MACH_NEO1973_GTA02
- if ((gta) && (bit == 9)) /* PMU */
- end += pcf50633_report_resumers(gta02_pcf_pdata.pcf, end);
+ if ((gta) && (bit == 9)); /* PMU */
+// end += pcf50633_report_resumers(gta02_pcf_pdata.pcf, end);
#endif
}
diff --git a/drivers/power/bq27000_battery.c b/drivers/power/bq27000_battery.c
index ccd56ea137c..dbbcdb379aa 100644
--- a/drivers/power/bq27000_battery.c
+++ b/drivers/power/bq27000_battery.c
@@ -125,8 +125,6 @@ struct bq27000_bat_regs {
struct bq27000_device_info {
struct device *dev;
struct power_supply bat;
- struct power_supply ac;
- struct power_supply usb;
struct delayed_work work;
struct bq27000_platform_data *pdata;
@@ -172,6 +170,7 @@ static void bq27000_battery_external_power_changed(struct power_supply *psy)
{
struct bq27000_device_info *di = container_of(psy, struct bq27000_device_info, bat);
+ power_supply_changed(&di->bat);
dev_dbg(di->dev, "%s\n", __FUNCTION__);
}
@@ -336,54 +335,6 @@ static void bq27000_battery_work(struct work_struct *work)
dev_err(di->dev, "battery service reschedule failed\n");
}
-static int ac_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- int ret = 0;
- struct bq27000_device_info *di = container_of(psy, struct bq27000_device_info, ac);
-
- if (!(di->pdata->hdq_initialized)())
- return -EINVAL;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- if (di->pdata->get_charger_online_status)
- val->intval = (di->pdata->get_charger_online_status)();
- else
- return -EINVAL;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static int usb_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- int ret = 0;
- struct bq27000_device_info *di = container_of(psy, struct bq27000_device_info, usb);
-
- if (!(di->pdata->hdq_initialized)())
- return -EINVAL;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- if (di->pdata->get_charger_online_status)
- val->intval = (di->pdata->get_charger_online_status)();
- else
- return -EINVAL;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
static enum power_supply_property bq27000_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_HEALTH,
@@ -399,10 +350,6 @@ static enum power_supply_property bq27000_battery_props[] = {
POWER_SUPPLY_PROP_ONLINE
};
-static enum power_supply_property power_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
-};
-
static int bq27000_battery_probe(struct platform_device *pdev)
{
int retval = 0;
@@ -432,36 +379,12 @@ static int bq27000_battery_probe(struct platform_device *pdev)
di->bat.use_for_apm = 1;
di->pdata = pdata;
- di->ac.name = "ac";
- di->ac.type = POWER_SUPPLY_TYPE_MAINS;
- di->ac.properties = power_props;
- di->ac.num_properties = ARRAY_SIZE(power_props);
- di->ac.get_property = ac_get_property;
-
- di->usb.name = "usb";
- di->usb.type = POWER_SUPPLY_TYPE_USB;
- di->usb.properties = power_props;
- di->usb.num_properties = ARRAY_SIZE(power_props);
- di->usb.get_property = usb_get_property;
-
retval = power_supply_register(&pdev->dev, &di->bat);
if (retval) {
dev_err(di->dev, "failed to register battery\n");
goto batt_failed;
}
- retval = power_supply_register(&pdev->dev, &di->ac);
- if (retval) {
- dev_err(di->dev, "failed to register ac\n");
- goto ac_failed;
- }
-
- retval = power_supply_register(&pdev->dev, &di->usb);
- if (retval) {
- dev_err(di->dev, "failed to register usb\n");
- goto usb_failed;
- }
-
INIT_DELAYED_WORK(&di->work, bq27000_battery_work);
if (!schedule_delayed_work(&di->work, 0))
@@ -469,10 +392,6 @@ static int bq27000_battery_probe(struct platform_device *pdev)
return 0;
-usb_failed:
- power_supply_unregister(&di->ac);
-ac_failed:
- power_supply_unregister(&di->bat);
batt_failed:
kfree(di);
di_alloc_failed:
@@ -486,24 +405,10 @@ static int bq27000_battery_remove(struct platform_device *pdev)
cancel_delayed_work(&di->work);
power_supply_unregister(&di->bat);
- power_supply_unregister(&di->ac);
- power_supply_unregister(&di->usb);
return 0;
}
-void bq27000_charging_state_change(struct platform_device *pdev)
-{
- struct bq27000_device_info *di = platform_get_drvdata(pdev);
-
- if (!di)
- return;
-
- power_supply_changed(&di->ac);
- power_supply_changed(&di->usb);
-}
-EXPORT_SYMBOL_GPL(bq27000_charging_state_change);
-
#ifdef CONFIG_PM
static int bq27000_battery_suspend(struct platform_device *pdev,
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index c7082d857d0..ef4165ae560 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -4,9 +4,11 @@
#include <linux/regulator/driver.h>
#include <linux/platform_device.h>
-#include <linux/pcf50633.h>
#include <linux/err.h>
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/pmic.h>
+
#define PCF50633_REGULATOR(_name, _id) \
{ \
.name = _name, \
@@ -16,7 +18,7 @@
.owner = THIS_MODULE, \
}
-static const u_int8_t regulator_registers[__NUM_PCF50633_REGULATORS] = {
+static const u_int8_t regulator_registers[PCF50633_NUM_REGULATORS] = {
[PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT,
[PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT,
[PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT,
@@ -93,11 +95,11 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
uint8_t regnr;
int regulator_id;
int millivolts;
- struct pcf50633_data *pcf = rdev_get_drvdata(rdev);;
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);;
regulator_id = rdev_get_id(rdev);
- if (regulator_id >= __NUM_PCF50633_REGULATORS)
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
millivolts = min_uV / 1000;
@@ -136,9 +138,9 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
uint8_t regnr;
unsigned int rc = 0;
int regulator_id = rdev_get_id(rdev);
- struct pcf50633_data *pcf = rdev_get_drvdata(rdev);
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);
- if (regulator_id >= __NUM_PCF50633_REGULATORS)
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
regnr = regulator_registers[regulator_id];
@@ -174,9 +176,9 @@ static int pcf50633_regulator_enable(struct regulator_dev *rdev)
{
uint8_t regnr;
int regulator_id = rdev_get_id(rdev);
- struct pcf50633_data *pcf = rdev_get_drvdata(rdev);
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);
- if (regulator_id >= __NUM_PCF50633_REGULATORS)
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
@@ -192,9 +194,9 @@ static int pcf50633_regulator_disable(struct regulator_dev *rdev)
{
uint8_t regnr;
int regulator_id = rdev_get_id(rdev);
- struct pcf50633_data *pcf = rdev_get_drvdata(rdev);
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);
- if (regulator_id >= __NUM_PCF50633_REGULATORS)
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
@@ -209,9 +211,9 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
{
uint8_t val, regnr;
int regulator_id = rdev_get_id(rdev);
- struct pcf50633_data *pcf = rdev_get_drvdata(rdev);
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);
- if (regulator_id >= __NUM_PCF50633_REGULATORS)
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
@@ -259,7 +261,7 @@ struct regulator_desc regulators[] = {
int __init pcf50633_regulator_probe(struct platform_device *pdev)
{
struct regulator_dev *rdev;
- struct pcf50633_data *pcf;
+ struct pcf50633 *pcf;
pcf = pdev->dev.driver_data;
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index 74b7e569d39..6b8ef2f4b8a 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -1,9 +1,9 @@
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/bcd.h>
-#include <linux/pcf50633.h>
-#include <linux/rtc/pcf50633.h>
-#include <linux/i2c.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/rtc.h>
enum pcf50633_time_indexes {
PCF50633_TI_SEC = 0,
@@ -46,69 +46,48 @@ static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc)
static int pcf50633_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
- struct pcf50633_data *pcf = dev->platform_data;
+ struct pcf50633 *pcf;
+
+ pcf = dev_get_drvdata(dev);
switch (cmd) {
case RTC_AIE_OFF:
/* disable the alarm interrupt */
- pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_INT1M,
- PCF50633_INT1_ALARM, PCF50633_INT1_ALARM);
+ pcf->rtc.alarm_enabled = 0;
+ pcf50633_irq_mask(pcf, PCF50633_IRQ_ALARM);
return 0;
case RTC_AIE_ON:
/* enable the alarm interrupt */
- pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_ALARM);
+ pcf->rtc.alarm_enabled = 1;
+ pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM);
return 0;
case RTC_PIE_OFF:
/* disable periodic interrupt (hz tick) */
- pcf->flags &= ~PCF50633_F_RTC_SECOND;
- pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_INT1M,
- PCF50633_INT1_SECOND, PCF50633_INT1_SECOND);
+ pcf->rtc.second_enabled = 0;
+ pcf50633_irq_mask(pcf, PCF50633_IRQ_SECOND);
return 0;
case RTC_PIE_ON:
/* ensable periodic interrupt (hz tick) */
- pcf->flags |= PCF50633_F_RTC_SECOND;
- pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_SECOND);
+ pcf->rtc.second_enabled = 1;
+ pcf50633_irq_unmask(pcf, PCF50633_IRQ_SECOND);
return 0;
}
return -ENOIOCTLCMD;
}
-#ifdef PCF50633_RTC
-void pcf50633_rtc_handle_event(struct pcf50633_data *pcf,
- enum pcf50633_rtc_event evt)
-{
- switch(evt) {
- case PCF50633_RTC_EVENT_ALARM:
- rtc_update_irq(pcf->rtc, 1, RTC_AF | RTC_IRQF);
- break;
- case PCF50633_RTC_EVENT_SECOND:
- rtc_update_irq(pcf->rtc, 1, RTC_PF | RTC_IRQF);
- }
-}
-#else
-void pcf50633_rtc_handle_event(struct pcf50633_data *pcf,
- enum pcf50633_rtc_event evt)
-{
-
-}
-#endif
-
static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
- struct pcf50633_data *pcf = dev->platform_data;
+ struct pcf50633 *pcf;
struct pcf50633_time pcf_tm;
int ret;
- mutex_lock(&pcf->lock);
+ pcf = dev_get_drvdata(dev);
- ret = i2c_smbus_read_i2c_block_data(pcf->client,
- PCF50633_REG_RTCSC,
+ ret = pcf50633_read_block(pcf, PCF50633_REG_RTCSC,
PCF50633_TI_EXTENT,
&pcf_tm.time[0]);
if (ret != PCF50633_TI_EXTENT)
- dev_err(dev, "Failed to read time :-(\n");
-
- mutex_unlock(&pcf->lock);
+ dev_err(dev, "Failed to read time\n");
dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
pcf_tm.time[PCF50633_TI_DAY],
@@ -129,9 +108,12 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
- struct pcf50633_data *pcf = dev->platform_data;
+ struct pcf50633 *pcf;
struct pcf50633_time pcf_tm;
int ret;
+ int second_masked, alarm_masked;
+
+ pcf = dev_get_drvdata(dev);
dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
tm->tm_mday, tm->tm_mon, tm->tm_year,
@@ -145,42 +127,46 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
pcf_tm.time[PCF50633_TI_MIN],
pcf_tm.time[PCF50633_TI_SEC]);
- mutex_lock(&pcf->lock);
- /* FIXME: disable second interrupt */
- ret = i2c_smbus_write_i2c_block_data(pcf->client,
- PCF50633_REG_RTCSC,
+ second_masked = pcf50633_irq_mask_get(pcf, PCF50633_IRQ_SECOND);
+ alarm_masked = pcf50633_irq_mask_get(pcf, PCF50633_IRQ_ALARM);
+
+ if (!second_masked)
+ pcf50633_irq_mask(pcf, PCF50633_IRQ_SECOND);
+ if (!alarm_masked)
+ pcf50633_irq_mask(pcf, PCF50633_IRQ_ALARM);
+
+ ret = pcf50633_write_block(pcf, PCF50633_REG_RTCSC,
PCF50633_TI_EXTENT,
&pcf_tm.time[0]);
if (ret)
dev_err(dev, "Failed to set time %d\n", ret);
- /* FIXME: re-enable second interrupt */
- mutex_unlock(&pcf->lock);
+ if (!second_masked)
+ pcf50633_irq_unmask(pcf, PCF50633_IRQ_SECOND);
+ if (!alarm_masked)
+ pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM);
+
return 0;
}
static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
- struct pcf50633_data *pcf = dev->platform_data;
+ struct pcf50633 *pcf;
struct pcf50633_time pcf_tm;
int ret;
- u_int8_t reg;
- mutex_lock(&pcf->lock);
-
- pcf50633_read(pcf, PCF50633_REG_INT1M, 1, &reg);
- alrm->enabled = reg & PCF50633_INT1_ALARM ? 0 : 1;
+ pcf = dev_get_drvdata(dev);
- ret = pcf50633_read(pcf, PCF50633_REG_RTCSCA,
+ alrm->enabled = pcf->rtc.alarm_enabled;
+
+ ret = pcf50633_read_block(pcf, PCF50633_REG_RTCSCA,
PCF50633_TI_EXTENT, &pcf_tm.time[0]);
if (ret != PCF50633_TI_EXTENT)
dev_err(dev, "Failed to read Alarm time :-(\n");
- mutex_unlock(&pcf->lock);
-
pcf2rtc_time(&alrm->time, &pcf_tm);
return 0;
@@ -188,35 +174,31 @@ static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
- struct pcf50633_data *pcf = dev->platform_data;
+ struct pcf50633 *pcf;
struct pcf50633_time pcf_tm;
- u_int8_t irqmask;
- int ret;
+ int ret, alarm_masked;
+
+ pcf = dev_get_drvdata(dev);
rtc2pcf_time(&pcf_tm, &alrm->time);
- mutex_lock(&pcf->lock);
+ printk("wkday is %x\n", alrm->time.tm_wday);
+ printk("wkday is %x\n", pcf_tm.time[PCF50633_TI_WKDAY]);
+
+ alarm_masked = pcf50633_irq_mask_get(pcf, PCF50633_IRQ_ALARM);
/* disable alarm interrupt */
- pcf50633_read(pcf, PCF50633_REG_INT1M, 1, &irqmask);
- irqmask |= PCF50633_INT1_ALARM;
- pcf50633_write(pcf, PCF50633_REG_INT1M, 1, &irqmask);
+ if (!alarm_masked)
+ pcf50633_irq_mask(pcf, PCF50633_IRQ_ALARM);
- ret = pcf50633_write(pcf, PCF50633_REG_RTCSCA,
+ ret = pcf50633_write_block(pcf, PCF50633_REG_RTCSCA,
PCF50633_TI_EXTENT, &pcf_tm.time[0]);
if (ret)
- dev_err(dev, "Failed to write alarm time :-( %d\n", ret);
-
- if (alrm->enabled) {
- /* (re-)enaable alarm interrupt */
- pcf50633_read(pcf, PCF50633_REG_INT1M, 1, &irqmask);
- irqmask &= ~PCF50633_INT1_ALARM;
- pcf50633_write(pcf, PCF50633_REG_INT1M, 1, &irqmask);
- }
+ dev_err(dev, "Failed to write alarm time %d\n", ret);
- mutex_unlock(&pcf->lock);
+ if (!alarm_masked)
+ pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM);
- /* FIXME */
return 0;
}
static struct rtc_class_ops pcf50633_rtc_ops = {
@@ -227,15 +209,32 @@ static struct rtc_class_ops pcf50633_rtc_ops = {
.set_alarm = pcf50633_rtc_set_alarm,
};
+static void pcf50633_rtc_irq(struct pcf50633 *pcf, int irq, void *unused)
+{
+ switch(irq) {
+ case PCF50633_IRQ_ALARM:
+ rtc_update_irq(pcf->rtc.rtc_dev, 1, RTC_AF | RTC_IRQF);
+ break;
+ }
+}
+
static int pcf50633_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
-
+ struct pcf50633 *pcf;
+
rtc = rtc_device_register("pcf50633", &pdev->dev,
&pcf50633_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return -ENODEV;
+ pcf = platform_get_drvdata(pdev);
+
+ /* Set up IRQ handlers */
+ pcf->irq_handler[PCF50633_IRQ_ALARM].handler = pcf50633_rtc_irq;
+ pcf->irq_handler[PCF50633_IRQ_SECOND].handler = pcf50633_rtc_irq;
+
+ pcf->rtc.rtc_dev = rtc;
return 0;
}
diff --git a/include/linux/bq27000_battery.h b/include/linux/bq27000_battery.h
index a617466a517..d65dc87a779 100644
--- a/include/linux/bq27000_battery.h
+++ b/include/linux/bq27000_battery.h
@@ -1,8 +1,6 @@
#ifndef __BQ27000_BATTERY_H__
#define __BQ27000_BATTERY_H__
-void bq27000_charging_state_change(struct platform_device *pdev);
-
struct bq27000_platform_data {
const char *name;
int rsense_mohms;
diff --git a/include/linux/rtc/pcf50633.h b/include/linux/rtc/pcf50633.h
deleted file mode 100644
index 4fc5898ed5d..00000000000
--- a/include/linux/rtc/pcf50633.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __LINUX_RTC_PCF50633_H
-#define __LINUX_RTC_PCF50633_H
-
-
-enum pcf50633_rtc_event {
- PCF50633_RTC_EVENT_ALARM,
- PCF50633_RTC_EVENT_SECOND,
-};
-
-void pcf50633_rtc_handle_event(struct pcf50633_data *pcf,
- enum pcf50633_rtc_event evt);
-
-#endif