[UPSTREAM 2/2] related changes to pcf50633_mdc.patch

Balaji Rao balajirrao at openmoko.org
Sun Nov 16 20:35:15 CET 2008


    Changes related to pcf50633_mfd.patch

diff --git a/arch/arm/mach-s3c2410/include/mach/gta02.h b/arch/arm/mach-s3c2410/include/mach/gta02.h
index 7f103bd..354043b 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 001fe3f..704ff67 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.charger_online;
 }
 
 static int gta02_get_charger_active_status(void)
 {
-	return gta02_charger_active_status;
+	struct pcf50633 *pcf = gta02_pcf_pdata.pcf;
+
+	return pcf->mbc.charger_active;
 }
 
 
@@ -499,39 +505,73 @@ struct platform_device bq27000_battery_device = {
 };
 
 
-/* PMU driver info */
+static void gta02_pmu_init(struct pcf50633 *pcf)
+{
+	/* 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);
+}
+
+#define ADC_NOM_CHG_DETECT_1A 6
+#define ADC_NOM_CHG_DETECT_USB 43
 
-static int pmu_callback(struct device *dev, unsigned int feature,
-			enum pmu_event event)
+static void
+gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
 {
-	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;
+	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;
+	} else
+		ma = 100;
+
+	pcf50633_mbc_usb_curlim_set(pcf, ma);
+	bq27000_charging_state_change(&bq27000_battery_device);
+}
+
+static struct delayed_work gta02_charger_work;
+static int gta02_usb_vbus_draw;
+
+static void gta02_charger_worker(struct work_struct *work)
+{
+	struct pcf50633 *pcf = gta02_pcf_pdata.pcf;
+
+	if (gta02_usb_vbus_draw) {
+		pcf50633_mbc_usb_curlim_set(pcf, gta02_usb_vbus_draw);
+
+		/* Wait for the PMU to reflect the new state */
+		bq27000_charging_state_change(&bq27000_battery_device);
+		return;
+	} else {
+		pcf50633_adc_async_read(pcf,
+			PCF50633_ADCC1_MUX_ADCIN1,
+			PCF50633_ADCC1_AVERAGE_16,
+			gta02_configure_pmu_for_charger, NULL);
+		return;
 	}
+}
 
+#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);
+		pcf50633_mbc_usb_curlim_set(pcf, 0);
+		gta02_usb_vbus_draw = 0;
+	}
+		
 	bq27000_charging_state_change(&bq27000_battery_device);
-	return 0;
 }
 
 static struct platform_device gta01_pm_gps_dev = {
@@ -556,8 +596,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",
@@ -592,20 +632,6 @@ static struct regulator_consumer_supply hcldo_consumers[] = {
 };
 
 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 |
@@ -613,9 +639,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
 		[1] = PCF50633_INT2_ONKEYF,
 		[2] = PCF50633_INT3_ONKEY1S
 	},
-	/* warning: these get rewritten during machine init below
-	 * depending on pcb variant
-	 */
 	.reg_init_data = {
 		[PCF50633_REGULATOR_AUTO] = {
 			.constraints = {
@@ -655,6 +678,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 +754,10 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
 		},
 
 	},
-	.attach_child_devices = gta02_pcf50633_attach_child_devices,
-	.regulator_registered = gta02_pcf50633_regulator_registered,
+	.init = gta02_pmu_init,
+	.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 +980,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 +1021,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);
 	u_int8_t ledena = 2;
@@ -1564,11 +1590,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:
@@ -1595,12 +1621,12 @@ 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,
@@ -1673,6 +1699,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 1e3d969..d3a046c 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 8f0a629..09b3bdc 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 ebed335..46c99c9 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 8ab589b..caa302e 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 a04466c..62984a5 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/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index c7082d8..ef4165a 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 74b7e56..c20a2ec 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -1,10 +1,11 @@
 #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,
 	PCF50633_TI_MIN,
@@ -46,70 +47,50 @@ 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,
+	ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client,
 					    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_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
 		pcf_tm.time[PCF50633_TI_DAY],
 		pcf_tm.time[PCF50633_TI_MONTH],
@@ -129,10 +110,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;
 
+	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,
 		tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -145,42 +128,35 @@ 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,
+	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);
 
 	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,33 +164,26 @@ 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;
 
+	pcf = dev_get_drvdata(dev);
+
 	rtc2pcf_time(&pcf_tm, &alrm->time);
 
-	mutex_lock(&pcf->lock);
 
 	/* disable alarm interrupt */
-	pcf50633_read(pcf, PCF50633_REG_INT1M, 1, &irqmask);
-	irqmask |= PCF50633_INT1_ALARM;
-	pcf50633_write(pcf, PCF50633_REG_INT1M, 1, &irqmask);
+	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);
-	}
+	if (alrm->enabled)
+		pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM);
 
-	mutex_unlock(&pcf->lock);
 
 	/* FIXME */
 	return 0;
@@ -227,15 +196,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/rtc/pcf50633.h b/include/linux/rtc/pcf50633.h
deleted file mode 100644
index 4fc5898..0000000
--- 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



More information about the openmoko-kernel mailing list