diff options
author | Balaji Rao <balajirrao@openmoko.org> | 2008-11-20 19:46:51 +0000 |
---|---|---|
committer | Andy Green <agreen@pads.home.warmcat.com> | 2008-11-20 19:46:51 +0000 |
commit | ad1e78fb2babc9cf9acd62923d62389ea28b1df2 (patch) | |
tree | dd37e7a75e654d38e601342cacd57a6b30cded8c | |
parent | 5557b3223d35dd25366d6ef047299b1dc94b17e6 (diff) |
pcf50633_mdc_related_changes.patch
Changes related to pcf50633_mfd.patch
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/gta02.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 169 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/neo1973_pm_bt.c | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/neo1973_pm_gps.c | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/neo1973_pm_gsm.c | 2 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/neo1973_pm_host.c | 2 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c | 6 | ||||
-rw-r--r-- | drivers/power/bq27000_battery.c | 97 | ||||
-rw-r--r-- | drivers/regulator/pcf50633-regulator.c | 28 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf50633.c | 147 | ||||
-rw-r--r-- | include/linux/bq27000_battery.h | 2 | ||||
-rw-r--r-- | include/linux/rtc/pcf50633.h | 13 |
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(>a02_charger_work, + GTA02_CHARGER_CONFIGURE_TIMEOUT); + return; + } else if (irq == PCF50633_IRQ_USBREM) { + cancel_delayed_work_sync(>a02_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[] = { >a02_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(>a02_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, ®); - 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 |