diff options
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 92 | ||||
-rw-r--r-- | drivers/mfd/pcf50633-core.c | 74 | ||||
-rw-r--r-- | drivers/power/pcf50633-charger.c | 81 | ||||
-rw-r--r-- | include/linux/mfd/pcf50633/core.h | 7 | ||||
-rw-r--r-- | include/linux/mfd/pcf50633/mbc.h | 13 |
5 files changed, 54 insertions, 213 deletions
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index d2556ed3a3a..e90f82bdfc3 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -557,9 +557,6 @@ static void gta02_charger_worker(struct work_struct *work) #define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000) static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq) { - int ret; - int happy_with_power = 0; - if (irq == PCF50633_IRQ_USBINS) { schedule_delayed_work(>a02_charger_work, GTA02_CHARGER_CONFIGURE_TIMEOUT); @@ -567,44 +564,6 @@ static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq) } else if (irq == PCF50633_IRQ_USBREM) { cancel_delayed_work_sync(>a02_charger_work); gta02_usb_vbus_draw = 0; - } else if (irq == PCF50633_ABOUT_TO_INCREASE_POWER) { - - /* - * we can't let this proceed until we are happy about - * power arrangements, because it is going to bring up - * the backlight and double our power consumption. - * - * With Qi/A6 anyway, until now we could boot just from - * USB 100mA limit and no or low battery. So we need - * to check for low battery and if so, spin here until - * USB enumerated power, or charger comes - */ - - while (!happy_with_power) { - ret = pcf50633_check_power_available(pcf); -// dev_info(pcf->dev, "available power = %d\n", ret); - switch (ret) { - case PCF50633_PA_DEAD_BATTERY_ONLY: - /* turn ourselves off */ - pcf50633_reg_write(pcf, PCF50633_REG_OOSHDWN, - 0x01); - break; - case PCF50633_PA_USB_100mA_AND_DEAD_BATTERY: - /* - * loop waiting for eg 500mA USB - * enumeration by host - */ - break; - default: - /* - * one way or another we can afford to - * use more power - */ - happy_with_power = 1; - continue; - } - msleep(1000); - } } } @@ -669,7 +628,6 @@ static char *gta02_batteries[] = { "battery", }; - struct pcf50633_platform_data gta02_pcf_pdata = { .resumers = { [0] = PCF50633_INT1_USBINS | @@ -807,7 +765,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = { .probe_done = gta02_pmu_attach_child_devices, .regulator_registered = gta02_pmu_regulator_registered, .mbc_event_callback = gta02_pmu_event_callback, - .good_main_battery_adc_threshold = 500 }; static void mangle_pmu_pdata_by_system_rev(void) @@ -1047,8 +1004,6 @@ static void gta02_udc_vbus_draw(unsigned int ma) return; } - printk(KERN_ERR "******** UDC gta02_pcf_pdata.pcf ma = %d\n", ma); - gta02_usb_vbus_draw = ma; schedule_delayed_work(>a02_charger_work, @@ -1653,7 +1608,20 @@ __setup("hardware_ecc=", hardware_ecc_setup); /* these are the guys that don't need to be children of PMU */ static struct platform_device *gta02_devices[] __initdata = { + >a02_version_device, + &s3c_device_usb, + &s3c_device_wdt, + >a02_memconfig_device, + &s3c_device_sdi, &s3c_device_usbgadget, + &s3c_device_nand, + >a02_nor_flash, + + &sc32440_fiq_device, + &s3c24xx_pwm_device, + >a02_led_dev, + >a02_pm_wlan_dev, /* not dependent on PMU */ + &s3c_device_iis, &s3c_device_i2c0, }; @@ -1661,15 +1629,6 @@ static struct platform_device *gta02_devices[] __initdata = { /* these guys DO need to be children of PMU */ static struct platform_device *gta02_devices_pmu_children[] = { - &s3c_device_usb, - &sc32440_fiq_device, - &s3c24xx_pwm_device, - &s3c_device_nand, - >a02_nor_flash, - >a02_pm_wlan_dev, /* not dependent on PMU */ - >a02_version_device, - &s3c_device_wdt, - >a02_memconfig_device, &s3c_device_ts, /* input 1 */ >a02_pm_gsm_dev, >a02_pm_usbhost_dev, @@ -1677,8 +1636,6 @@ static struct platform_device *gta02_devices_pmu_children[] = { &s3c_device_spi_acc2, /* input 3 */ >a02_button_dev, /* input 4 */ >a02_resume_reason_device, - &s3c_device_sdi, - >a02_led_dev, }; static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id) @@ -1688,24 +1645,23 @@ static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id) regulator = pcf->pmic.pdev[id]; switch(id) { - case PCF50633_REGULATOR_LDO4: - pdev = >a01_pm_bt_dev; - break; - case PCF50633_REGULATOR_LDO5: - pdev = >a01_pm_gps_dev; - break; - case PCF50633_REGULATOR_HCLDO: - pdev = >a02_glamo_dev; - break; - default: - return; + case PCF50633_REGULATOR_LDO4: + pdev = >a01_pm_bt_dev; + break; + case PCF50633_REGULATOR_LDO5: + pdev = >a01_pm_gps_dev; + break; + case PCF50633_REGULATOR_HCLDO: + pdev = >a02_glamo_dev; + break; + default: + return; } pdev->dev.parent = ®ulator->dev; platform_device_register(pdev); } - /* this is called when pc50633 is probed, unfortunately quite late in the * day since it is an I2C bus device. Here we can belatedly define some * platform devices with the advantage that we can mark the pcf50633 as the diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 2079d303000..6634558ea91 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -28,7 +28,6 @@ #include <linux/interrupt.h> #include <linux/workqueue.h> #include <linux/platform_device.h> -#include <linux/delay.h> #include <linux/mfd/pcf50633/core.h> @@ -293,11 +292,10 @@ static void pcf50633_irq_worker(struct work_struct *work) pcf_int[0] &= ~(1 << PCF50633_INT1_ADPINS); } -#if 0 dev_info(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x " "INT4=0x%02x INT5=0x%02x\n", pcf_int[0], pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]); -#endif + /* Some revisions of the chip don't have a 8s standby mode on * ONKEY1S press. We try to manually do it in such cases. */ @@ -379,6 +377,8 @@ static irqreturn_t pcf50633_irq(int irq, void *data) { struct pcf50633 *pcf = data; + printk(KERN_ERR "pcf50633_irq\n"); + get_device(pcf->dev); disable_irq(pcf->irq); @@ -474,17 +474,15 @@ static int pcf50633_resume(struct device *dev) #define pcf50633_resume NULL #endif - static int pcf50633_probe(struct i2c_client *client, const struct i2c_device_id *ids) { struct pcf50633 *pcf; struct pcf50633_platform_data *pdata; - int ret = 0; + int i, ret = 0; + u8 mbcs1; int version; int variant; - u8 mbcs1; - int i; pdata = client->dev.platform_data; @@ -520,7 +518,7 @@ static int pcf50633_probe(struct i2c_client *client, dev_info(pcf->dev, "Probed device version %d variant %d\n", version, variant); - /* Enable all interrupts except RTC SECOND */ + /* Enable all inteerupts except RTC SECOND */ pcf->mask_regs[0] = 0x80; pcf50633_reg_write(pcf, PCF50633_REG_INT1M, 0x80); @@ -537,15 +535,22 @@ static int pcf50633_probe(struct i2c_client *client, &pcf->mbc.pdev); pcf50633_client_dev_register(pcf, "pcf50633-adc", &pcf->adc.pdev); + for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { + struct platform_device *pdev; - /* Cold Intialization */ - mbcs1 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS1); + pdev = platform_device_alloc("pcf50633-regltr", i); + if (!pdev) { + dev_err(pcf->dev, "Cannot create regulator\n"); + continue; + } - if (mbcs1 & 0x01) - pcf50633_irq_call_handler(pcf, PCF50633_IRQ_USBINS); - if (mbcs1 & 0x04) - pcf50633_irq_call_handler(pcf, PCF50633_IRQ_ADPINS); + pdev->dev.parent = pcf->dev; + pdev->dev.platform_data = &pdata->reg_init_data[i]; + pdev->dev.driver_data = pcf; + pcf->pmic.pdev[i] = pdev; + platform_device_add(pdev); + } pcf->irq = client->irq; @@ -566,41 +571,20 @@ static int pcf50633_probe(struct i2c_client *client, dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up " "source in this hardware revision\n", client->irq); + /* Cold Intialization */ + mbcs1 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS1); + + if (mbcs1 & 0x01) + pcf50633_irq_call_handler(pcf, PCF50633_IRQ_USBINS); + if (mbcs1 & 0x04) + pcf50633_irq_call_handler(pcf, PCF50633_IRQ_ADPINS); + ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group); if (ret) dev_err(pcf->dev, "error creating sysfs entries\n"); - /* - * give the system a chance to spin until power situation becomes - * good enough to continue boot. USB-based systems are only allowed to - * pull 100mA until enumerated when they can have up to 500mA for - * example - */ - - if (pcf->pdata->mbc_event_callback) - pcf->pdata->mbc_event_callback(pcf, - PCF50633_ABOUT_TO_INCREASE_POWER); - - for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { - struct platform_device *pdev; - - pdev = platform_device_alloc("pcf50633-regltr", i); - if (!pdev) { - dev_err(pcf->dev, "Cannot create regulator\n"); - continue; - } - - pdev->dev.parent = pcf->dev; - pdev->dev.platform_data = &pcf->pdata->reg_init_data[i]; - pdev->dev.driver_data = pcf; - pcf->pmic.pdev[i] = pdev; - - platform_device_add(pdev); - } - - if (pcf->pdata->probe_done) - pcf->pdata->probe_done(pcf); - + if (pdata->probe_done) + pdata->probe_done(pcf); return 0; diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 8e302c6c40e..9bbfaac48a1 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -23,90 +23,9 @@ * MA 02111-1307 USA */ -#include <linux/delay.h> #include <linux/mfd/pcf50633/core.h> #include <linux/mfd/pcf50633/mbc.h> -/* this tells us the answer to "how am I set for power?" */ - -enum pcf50633_power_avail pcf50633_check_power_available(struct pcf50633 *pcf) -{ - int ret; - int battery_ok; - int usb_present; - - /* first look for adapter and USB power status */ - - ret = pcf50633_reg_read(pcf, PCF50633_REG_MBCS1); - if (ret < 0) - return ret; - - if (ret & 8) /* adapter power present */ - return PCF50633_PA_ADAPTER; /* don't care about anything else */ - - usb_present = ret & 2; - - /* measure battery using PMU ADC */ - /* disable charging momentarily so we can measure battery */ - - ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, 1, 0); - if (ret < 0) - return ret; - - ret = pcf50633_adc_sync_read(pcf, PCF50633_ADCC1_MUX_BATSNS_RES, - PCF50633_ADCC1_AVERAGE_16); - if (ret < 0) - return ret; - - battery_ok = (ret > pcf->pdata->good_main_battery_adc_threshold); - - /* enable charging again */ - - ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, 1, 1); - if (ret < 0) - return ret; - - /* - * now we know battery and USB situation - * make the decision now if possible - */ - - if (!usb_present && !battery_ok) - return PCF50633_PA_DEAD_BATTERY_ONLY; - - if (!usb_present && battery_ok) - return PCF50633_PA_LIVE_BATTERY_ONLY; - - /* So USB is present... what current limit? */ - - ret = pcf50633_reg_read(pcf, PCF50633_REG_MBCC7); - if (ret < 0) - return ret; - - switch (ret & PCF50633_MBCC7_USB_MASK) { - - case PCF50633_MBCC7_USB_100mA: - if (battery_ok) - return PCF50633_PA_USB_100mA_AND_LIVE_BATTERY; - else - return PCF50633_PA_USB_100mA_AND_DEAD_BATTERY; - - case PCF50633_MBCC7_USB_500mA: - return PCF50633_PA_USB_500mA; - - case PCF50633_MBCC7_USB_1000mA: - return PCF50633_PA_USB_1A; - - default: - if (battery_ok) - return PCF50633_PA_LIVE_BATTERY_ONLY; - else - return PCF50633_PA_DEAD_BATTERY_ONLY; - } - - return PCF50633_PA_DEAD_BATTERY_ONLY; -} - void pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) { int ret; diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h index 4ee3f527172..bf107d3794e 100644 --- a/include/linux/mfd/pcf50633/core.h +++ b/include/linux/mfd/pcf50633/core.h @@ -34,8 +34,6 @@ struct pcf50633_platform_data { char **batteries; int num_batteries; - int good_main_battery_adc_threshold; - /* Callbacks */ void (*probe_done)(struct pcf50633 *); void (*mbc_event_callback)(struct pcf50633 *, int); @@ -80,7 +78,6 @@ int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 bits); #define PCF50633_REG_INT3M 0x09 #define PCF50633_REG_INT4M 0x0a #define PCF50633_REG_INT5M 0x0b -#define PCF50633_REG_OOSHDWN 0x0c enum { /* Chip IRQs */ @@ -125,10 +122,8 @@ enum { PCF50633_IRQ_HCLDOPWRFAIL, PCF50633_IRQ_HCLDOOVL, - /* Always last of real IRQs */ + /* Always last */ PCF50633_NUM_IRQ, - /* fake IRQ */ - PCF50633_ABOUT_TO_INCREASE_POWER }; struct pcf50633 { diff --git a/include/linux/mfd/pcf50633/mbc.h b/include/linux/mfd/pcf50633/mbc.h index a1cd44957ac..9a7938ad132 100644 --- a/include/linux/mfd/pcf50633/mbc.h +++ b/include/linux/mfd/pcf50633/mbc.h @@ -15,7 +15,6 @@ #include <linux/platform_device.h> -#define PCF50633_REG_BVMCTL 0x19 #define PCF50633_REG_MBCC1 0x43 #define PCF50633_REG_MBCC2 0x44 #define PCF50633_REG_MBCC3 0x45 @@ -123,18 +122,6 @@ struct pcf50633; void pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma); -enum pcf50633_power_avail { - PCF50633_PA_DEAD_BATTERY_ONLY, - PCF50633_PA_LIVE_BATTERY_ONLY, - PCF50633_PA_ADAPTER, - PCF50633_PA_USB_100mA_AND_LIVE_BATTERY, - PCF50633_PA_USB_100mA_AND_DEAD_BATTERY, - PCF50633_PA_USB_500mA, - PCF50633_PA_USB_1A -}; - -enum pcf50633_power_avail pcf50633_check_power_available(struct pcf50633 *pcf); - struct pcf50633_mbc { int adapter_active; int adapter_online; |