diff options
author | Balaji Rao <balajirrao@openmoko.org> | 2009-01-27 14:38:49 +0000 |
---|---|---|
committer | Andy Green <agreen@octopus.localdomain> | 2009-01-27 14:38:49 +0000 |
commit | 57a4af9be7051302edc51c878ecfbd90466827ff (patch) | |
tree | 51c5f9149184b63de61af0ba5dc79fa931c5aab7 /arch/arm/mach-s3c2410 | |
parent | cc0a09e9e49f6121622d8579b23018e378a29e23 (diff) |
Subject: pcf50606_rebase_changes,patch
X-Git-Url: http://git.openmoko.org/?p=kernel.git;a=commitdiff_plain;h=445395c9fcfb78ea62ab5a69b84c2c12efe01cff
pcf50606_rebase_changes,patch
This patch brings into andy-tracking all changes related to pcf50606 from old
balaji-tracking.
Diffstat (limited to 'arch/arm/mach-s3c2410')
-rw-r--r-- | arch/arm/mach-s3c2410/Kconfig | 12 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/gta01.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/mach-gta01.c | 470 |
3 files changed, 315 insertions, 169 deletions
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 25ebd38539e..ba58f9cac95 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -143,7 +143,17 @@ config MACH_NEO1973_GTA01 bool "FIC Neo1973 GSM Phone (GTA01 Hardware)" select CPU_S3C2410 select MACH_NEO1973 - select SENSORS_PCF50606 + select MFD_PCF50606 + select INPUT_PCF50606_PMU + select PCF50606_ADC + select PCF50606_GPIO + select RTC_DRV_PCF50606 + select REGULATOR_PCF50606 + select CHARGER_PCF50606 + select PCF50606_WATCHDOG + select POWER_SUPPLY + select BATTERY_GTA01 + help Say Y here if you are using the FIC Neo1973 GSM Phone diff --git a/arch/arm/mach-s3c2410/include/mach/gta01.h b/arch/arm/mach-s3c2410/include/mach/gta01.h index 7af36a1bc86..99181170624 100644 --- a/arch/arm/mach-s3c2410/include/mach/gta01.h +++ b/arch/arm/mach-s3c2410/include/mach/gta01.h @@ -71,4 +71,6 @@ struct gta01bl_machinfo { #define GTA01Bv4_IRQ_PCF50606 IRQ_EINT9 +extern struct pcf50606 *gta01_pcf; + #endif /* _GTA01_H */ diff --git a/arch/arm/mach-s3c2410/mach-gta01.c b/arch/arm/mach-s3c2410/mach-gta01.c index 117062c959f..629fb7a49b6 100644 --- a/arch/arm/mach-s3c2410/mach-gta01.c +++ b/arch/arm/mach-s3c2410/mach-gta01.c @@ -47,7 +47,16 @@ #include <linux/mmc/host.h> -#include <linux/pcf50606.h> +#include <linux/mfd/pcf50606/core.h> +#include <linux/mfd/pcf50606/pmic.h> +#include <linux/mfd/pcf50606/mbc.h> +#include <linux/mfd/pcf50606/adc.h> + +#include <linux/gta01_battery.h> + +#include <linux/regulator/machine.h> +#include <linux/regulator/consumer.h> + #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -60,7 +69,6 @@ #include <mach/regs-gpio.h> #include <mach/fb.h> -#include <mach/mci.h> #include <mach/spi.h> #include <mach/spi-gpio.h> #include <mach/usb-control.h> @@ -74,14 +82,14 @@ #include <plat/pm.h> #include <plat/udc.h> #include <plat/iic.h> +#include <plat/mci.h> #include <asm/plat-s3c24xx/neo1973.h> #include <mach/neo1973-pm-gsm.h> #include <linux/jbt6k74.h> -#include <linux/ts_filter_mean.h> -#include <linux/ts_filter_median.h> - +#include <../drivers/input/touchscreen/ts_filter_mean.h> +#include <../drivers/input/touchscreen/ts_filter_median.h> static struct map_desc gta01_iodesc[] __initdata = { { @@ -115,8 +123,14 @@ static struct s3c2410_uartcfg gta01_uartcfgs[] = { }, }; -/* PMU driver info */ +/* TODO */ +static void gta01_pmu_event_callback(struct pcf50606 *pcf, int irq) +{ + /*TODO : Handle ACD here */ +} +/* FIXME : Goes away when ACD is handled above */ +#if 0 static int pmu_callback(struct device *dev, unsigned int feature, enum pmu_event event) { @@ -139,152 +153,316 @@ static int pmu_callback(struct device *dev, unsigned int feature, return 0; } +#endif + +struct pcf50606 *gta01_pcf; + +static struct platform_device gta01_pm_gsm_dev = { + .name = "neo1973-pm-gsm", +}; + +static struct platform_device gta01_pm_bt_dev = { + .name = "neo1973-pm-bt", +}; +static struct platform_device gta01_pm_gps_dev = { + .name = "neo1973-pm-gps", +}; + +static struct regulator_consumer_supply ioreg_consumers[] = { + { + .dev = >a01_pm_gps_dev.dev, + .supply = "GPS_2V8", + }, +}; + +static struct regulator_consumer_supply d1reg_consumers[] = { + { + .dev = >a01_pm_gps_dev.dev, + .supply = "GPS_3V", + }, + { + .dev = >a01_pm_bt_dev.dev, + .supply = "BT_3V1", + }, +}; + +static struct regulator_consumer_supply dcd_consumers[] = { + { + .dev = >a01_pm_gps_dev.dev, + .supply = "GPS_3V3", + }, + { + .dev = >a01_pm_gps_dev.dev, + .supply = "GPS_1V5", + }, +}; + +static struct regulator_consumer_supply d2reg_consumers[] = { + { + .dev = >a01_pm_gps_dev.dev, + .supply = "GPS_2V5", + }, + { + .dev = &s3c_device_sdi.dev, + .supply = "SD_3V3", + }, +}; + +static int gta01_bat_get_charging_status(void) +{ + struct pcf50606 *pcf = gta01_pcf; + u8 mbcc1, chgmod; + + mbcc1 = pcf50606_reg_read(pcf, PCF50606_REG_MBCC1); + chgmod = mbcc1 & PCF50606_MBCC1_CHGMOD_MASK; + + if (chgmod == PCF50606_MBCC1_CHGMOD_IDLE) + return 0; + else + return 1; +} + +static int gta01_bat_get_voltage(void) +{ + struct pcf50606 *pcf = gta01_pcf; + u16 adc, mv = 0; + + adc = pcf50606_adc_sync_read(pcf, PCF50606_ADCMUX_BATVOLT_RES); + mv = (adc * 6000) / 1024; + + return mv; +} + +static int gta01_bat_get_current(void) +{ + struct pcf50606 *pcf = gta01_pcf; + u16 adc_battvolt, adc_adcin1; + s32 res; + + adc_battvolt = pcf50606_adc_sync_read(pcf, PCF50606_ADCMUX_BATVOLT_SUBTR); + adc_adcin1 = pcf50606_adc_sync_read(pcf, PCF50606_ADCMUX_ADCIN1_SUBTR); + res = (adc_adcin1 - adc_battvolt) * 2400; + + /*rsense is 220 milli */ + return (res * 1000) / (220 * 1024); +} + +static struct gta01_bat_platform_data gta01_bat_pdata = { + .get_charging_status = gta01_bat_get_charging_status, + .get_voltage = gta01_bat_get_voltage, + .get_current = gta01_bat_get_current, +}; + +struct platform_device gta01_bat = { + .name = "gta01_battery", + .id = -1, + .dev = { + .platform_data = >a01_bat_pdata, + } +}; + +static void gta01_pcf_probe_done(struct pcf50606 *pcf) +{ + gta01_pcf = pcf; + gta01_bat.dev.parent = pcf->dev; + platform_device_register(>a01_bat); +} + +static int gps_registered_regulators = 0; + +static void gta01_pmu_regulator_registered(struct pcf50606 *pcf, int id) +{ + switch(id) { + case PCF50606_REGULATOR_D1REG: + platform_device_register(>a01_pm_bt_dev); + gps_registered_regulators++; + break; + case PCF50606_REGULATOR_D2REG: + gps_registered_regulators++; + platform_device_register(&s3c_device_sdi); + break; + case PCF50606_REGULATOR_IOREG: + case PCF50606_REGULATOR_DCD: + gps_registered_regulators++; + break; + } + + /* All GPS related regulators registered ? */ + if (gps_registered_regulators == 4) + platform_device_register(>a01_pm_gps_dev); + +} static struct pcf50606_platform_data gta01_pcf_pdata = { - .used_features = PCF50606_FEAT_EXTON | - PCF50606_FEAT_MBC | - PCF50606_FEAT_BBC | - PCF50606_FEAT_RTC | - PCF50606_FEAT_WDT | - PCF50606_FEAT_CHGCUR | - PCF50606_FEAT_BATVOLT | - PCF50606_FEAT_BATTEMP, - .onkey_seconds_required = 3, - .cb = &pmu_callback, - .r_fix_batt = 10000, - .r_fix_batt_par = 10000, - .r_sense_milli = 220, - .rails = { + .resumers = { + [0] = PCF50606_INT1_ALARM | + PCF50606_INT1_ONKEYF | + PCF50606_INT1_EXTONR, + [1] = PCF50606_INT2_CHGWD10S | + PCF50606_INT2_CHGPROT | + PCF50606_INT2_CHGERR, + [2] = PCF50606_INT3_LOWBAT | + PCF50606_INT3_HIGHTMP | + PCF50606_INT3_ACDINS, + }, + .mbc_event_callback = gta01_pmu_event_callback, + .reg_init_data = { [PCF50606_REGULATOR_D1REG] = { - .name = "bt_3v15", - .voltage = { - .init = 3150, - .max = 3150, + .constraints = { + .min_uV = 3000000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, }, + .num_consumer_supplies = ARRAY_SIZE(d1reg_consumers), + .consumer_supplies = d1reg_consumers, }, + [PCF50606_REGULATOR_D2REG] = { - .name = "gl_2v5", - .voltage = { - .init = 2500, - .max = 2500, + .constraints = { + .min_uV = 1650000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .apply_uV = 1, }, + .num_consumer_supplies = ARRAY_SIZE(d2reg_consumers), + .consumer_supplies = d2reg_consumers, + }, + [PCF50606_REGULATOR_D3REG] = { - .name = "stby_1v8", - .flags = PMU_VRAIL_F_SUSPEND_ON, - .voltage = { - .init = 1800, - .max = 2100, + .constraints = { + .min_uV = 1800000, + .max_uV = 2100000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .state_mem = { + .enabled = 1, + }, }, + .num_consumer_supplies = 0, }, + [PCF50606_REGULATOR_DCD] = { - .name = "gl_1v5", - .voltage = { - .init = 1500, - .max = 1500, + .constraints = { + .min_uV = 1500000, + .max_uV = 1500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, }, + .num_consumer_supplies = ARRAY_SIZE(dcd_consumers), + .consumer_supplies = dcd_consumers, }, + [PCF50606_REGULATOR_DCDE] = { - .name = "io_3v3", - .flags = PMU_VRAIL_F_SUSPEND_ON, - .voltage = { - .init = 3300, - .max = 3330, + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, + .state_mem = { + .enabled = 1, + }, }, + .num_consumer_supplies = 0, }, + [PCF50606_REGULATOR_DCUD] = { - .name = "core_1v8", - .flags = PMU_VRAIL_F_SUSPEND_ON, - .voltage = { - .init = 2100, - .max = 2100, + .constraints = { + .min_uV = 2100000, + .max_uV = 2100000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, + .state_mem = { + .enabled = 1, + }, }, + .num_consumer_supplies = 0, }, + [PCF50606_REGULATOR_IOREG] = { - .name = "codec_3v3", - .voltage = { - .init = 3300, - .max = 3300, + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, }, + .num_consumer_supplies = ARRAY_SIZE(ioreg_consumers), + .consumer_supplies = ioreg_consumers, + }, + [PCF50606_REGULATOR_LPREG] = { - .name = "lcm_3v3", - .voltage = { - .init = 3300, - .max = 3300, + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, }, - } + .num_consumer_supplies = 0, + }, }, + .probe_done = gta01_pcf_probe_done, + .regulator_registered = gta01_pmu_regulator_registered, }; -static void cfg_pmu_vrail(struct pmu_voltage_rail *vrail, char *name, - unsigned int flags, unsigned int init, +static void cfg_pmu_vrail(struct regulator_init_data *vrail, + unsigned int suspend_on, unsigned int min, unsigned int max) { - vrail->name = name; - vrail->flags = flags; - vrail->voltage.init = init; - vrail->voltage.max = max; + vrail->constraints.state_mem.enabled = suspend_on; + vrail->constraints.min_uV = min; + vrail->constraints.max_uV = min; + vrail->constraints.apply_uV = 1; } static void mangle_pmu_pdata_by_system_rev(void) { + struct regulator_init_data *reg_init_data; + + reg_init_data = gta01_pcf_pdata.reg_init_data; + switch (system_rev) { case GTA01Bv4_SYSTEM_REV: - gta01_pcf_pdata.used_features |= PCF50606_FEAT_ACD; + + /* FIXME : gta01_pcf_pdata.used_features |= PCF50606_FEAT_ACD; */ break; case GTA01Bv3_SYSTEM_REV: case GTA01Bv2_SYSTEM_REV: - gta01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG] - .name = "user1"; - gta01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG] - .flags &= ~PMU_VRAIL_F_SUSPEND_ON; - gta01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG] - .flags = PMU_VRAIL_F_UNUSED; + reg_init_data[PCF50606_REGULATOR_D3REG].constraints.state_mem.enabled = 1; break; case GTA01v4_SYSTEM_REV: - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCUD], - "core_1v8", PMU_VRAIL_F_SUSPEND_ON, 1800, 1800); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D1REG], - "vrf_3v", 0, 3000, 3000); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG], - "vtcxo_2v8", 0, 2800, 2800); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCD], - "gl_3v5", 0, 3500, 3500); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCUD], + 1, 18000000, 1800000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D1REG], + 0, 3000000, 3000000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D3REG], + 0, 2800000, 2800000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCD], + 0, 3500000, 3500000); break; case GTA01v3_SYSTEM_REV: - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D1REG], - "vrf_3v", 0, 3000, 3000); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D2REG], - "sd_3v3", 0, 3300, 3300); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG], - "codec_3v3", 0, 3300, 3300); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCD], - "gpsio_3v3", 0, 3300, 3300); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCUD], - "core_1v8", PMU_VRAIL_F_SUSPEND_ON, 1800, 1800); - cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_IOREG], - "vtcxo_2v8", 0, 2800, 2800); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D1REG], + 0, 3000000, 3000000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D2REG], + 0, 3300000, 3300000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D3REG], + 0, 3300000, 3300000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCD], + 0, 3300000, 3300000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCUD], + 1, 1800000, 1800000); + cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_IOREG], + 0, 2800000, 2800000); break; } } -static struct resource gta01_pmu_resources[] = { - [0] = { - .flags = IORESOURCE_IRQ, - .start = GTA01_IRQ_PCF50606, - .end = GTA01_IRQ_PCF50606, - }, -}; - -struct platform_device gta01_pmu_dev = { - .name = "pcf50606", - .num_resources = ARRAY_SIZE(gta01_pmu_resources), - .resource = gta01_pmu_resources, - .dev = { - .platform_data = >a01_pcf_pdata, - }, -}; +static void gta01_power_off(void) +{ + pcf50606_reg_write(gta01_pcf, PCF50606_REG_OOCC1, + PCF50606_OOCC1_GOSTDBY); +} /* LCD driver info */ @@ -373,7 +551,6 @@ static struct platform_device *gta01_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, - &s3c_device_sdi, &s3c_device_usbgadget, &s3c_device_nand, &s3c_device_ts, @@ -395,52 +572,8 @@ static struct s3c2410_platform_nand gta01_nand_info = { .sets = gta01_nand_sets, }; -static void gta01_mmc_set_power(unsigned char power_mode, unsigned short vdd) -{ - int bit; - int mv = 1700; /* 1.7V for MMC_VDD_165_195 */ - - printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u)\n", - power_mode, vdd); - - switch (system_rev) { - case GTA01v3_SYSTEM_REV: - switch (power_mode) { - case MMC_POWER_OFF: - pcf50606_onoff_set(pcf50606_global, - PCF50606_REGULATOR_D2REG, 0); - break; - case MMC_POWER_ON: - /* translate MMC_VDD_* VDD bit to mv */ - for (bit = 8; bit != 24; bit++) - if (vdd == (1 << bit)) - mv += 100 * (bit - 4); - pcf50606_voltage_set(pcf50606_global, - PCF50606_REGULATOR_D2REG, mv); - pcf50606_onoff_set(pcf50606_global, - PCF50606_REGULATOR_D2REG, 1); - break; - } - break; - case GTA01v4_SYSTEM_REV: - case GTA01Bv2_SYSTEM_REV: - case GTA01Bv3_SYSTEM_REV: - case GTA01Bv4_SYSTEM_REV: - switch (power_mode) { - case MMC_POWER_OFF: - neo1973_gpb_setpin(GTA01_GPIO_SDMMC_ON, 1); - break; - case MMC_POWER_ON: - neo1973_gpb_setpin(GTA01_GPIO_SDMMC_ON, 0); - break; - } - break; - } -} - static struct s3c24xx_mci_pdata gta01_mmc_cfg = { .gpio_detect = GTA01_GPIO_nSD_DETECT, - .set_power = >a01_mmc_set_power, .ocr_avail = MMC_VDD_165_195|MMC_VDD_20_21| MMC_VDD_21_22|MMC_VDD_22_23|MMC_VDD_23_24| MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27| @@ -478,17 +611,17 @@ static void __gta01_udc_vbus_draw(struct work_struct *work) /* this is a fix to work around boot-time ordering problems if the * s3c2410_udc is initialized before the pcf50606 driver has defined * pcf50606_global */ - if (!pcf50606_global) + if (!gta01_pcf) return; if (gta01_udc_vbus_drawer.ma >= 500) { /* enable fast charge */ printk(KERN_DEBUG "udc: enabling fast charge\n"); - pcf50606_charge_fast(pcf50606_global, 1); + pcf50606_charge_fast(gta01_pcf, 1); } else { /* disable fast charge */ printk(KERN_DEBUG "udc: disabling fast charge\n"); - pcf50606_charge_fast(pcf50606_global, 0); + pcf50606_charge_fast(gta01_pcf, 1); } } @@ -661,14 +794,6 @@ static struct resource gta01_button_resources[] = { .start = GTA01_GPIO_JACK_INSERT, .end = GTA01_GPIO_JACK_INSERT, }, - [3] = { - .start = 0, - .end = 0, - }, - [4] = { - .start = 0, - .end = 0, - }, }; struct platform_device gta01_button_dev = { @@ -677,10 +802,6 @@ struct platform_device gta01_button_dev = { .resource = gta01_button_resources, }; -static struct platform_device gta01_pm_gsm_dev = { - .name = "neo1973-pm-gsm", -}; - /* USB */ static struct s3c2410_hcd_info gta01_usb_info = { .port[0] = { @@ -705,6 +826,17 @@ static irqreturn_t gta01_modem_irq(int irq, void *param) return IRQ_HANDLED; } +static struct i2c_board_info gta01_i2c_devs[] __initdata = { + { + I2C_BOARD_INFO("pcf50606", 0x08), + .irq = GTA01_IRQ_PCF50606, + .platform_data = >a01_pcf_pdata, + }, + { + I2C_BOARD_INFO("lm4587", 0x7c), + } +}; + static void __init gta01_machine_init(void) { int rc; @@ -753,14 +885,14 @@ static void __init gta01_machine_init(void) gta01_led_resources[0].end = GTA01Bv2_GPIO_VIBRATOR_ON; break; case GTA01Bv4_SYSTEM_REV: - gta01_pmu_resources[0].start = - gta01_pmu_resources[0].end = GTA01Bv4_IRQ_PCF50606; + gta01_i2c_devs[0].irq = GTA01Bv4_IRQ_PCF50606; gta01_led_resources[0].start = gta01_led_resources[0].end = GTA01Bv4_GPIO_VIBRATOR_ON; break; } mangle_pmu_pdata_by_system_rev(); - platform_device_register(>a01_pmu_dev); + i2c_register_board_info(0, gta01_i2c_devs, ARRAY_SIZE(gta01_i2c_devs)); + platform_device_register(>a01_led_dev); platform_add_devices(gta01_devices, ARRAY_SIZE(gta01_devices)); @@ -773,6 +905,8 @@ static void __init gta01_machine_init(void) enable_irq_wake(GTA01_IRQ_MODEM); printk(KERN_DEBUG "Enabled GSM wakeup IRQ %d (rc=%d)\n", GTA01_IRQ_MODEM, rc); + + pm_power_off = >a01_power_off; } MACHINE_START(NEO1973_GTA01, "GTA01") |