static int __init sharpsl_pm_probe(struct platform_device *pdev) { if (!pdev->dev.platform_data) return -EINVAL; sharpsl_pm.dev = &pdev->dev; sharpsl_pm.machinfo = pdev->dev.platform_data; sharpsl_pm.charge_mode = CHRG_OFF; sharpsl_pm.flags = 0; sharpsl_pm.machinfo->init(); init_timer(&sharpsl_pm.ac_timer); sharpsl_pm.ac_timer.function = sharpsl_ac_timer; init_timer(&sharpsl_pm.chrg_full_timer); sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN); pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN); pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN); /* Register interrupt handlers */ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); } else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE); if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); } else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING); if (sharpsl_pm.machinfo->gpio_fatal) { if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); } else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING); } if (!machine_is_corgi()) { /* Register interrupt handler. */ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); } else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING); } device_create_file(&pdev->dev, &dev_attr_battery_percentage); device_create_file(&pdev->dev, &dev_attr_battery_voltage); apm_get_power_status = sharpsl_apm_get_power_status; pm_set_ops(&sharpsl_pm_ops); mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); return 0; }
static void corgi_restart(char mode, const char *cmd) { if (!machine_is_corgi()) gpio_set_value(CORGI_GPIO_LED_GREEN, 1); arm_machine_restart('h', cmd); }
static void corgi_poweroff(void) { if (!machine_is_corgi()) gpio_set_value(CORGI_GPIO_LED_GREEN, 0); arm_machine_restart('h', NULL); }
static void corgi_poweroff(void) { if (!machine_is_corgi()) /* Green LED off tells the bootloader to halt */ gpio_set_value(CORGI_GPIO_LED_GREEN, 0); arm_machine_restart('h', NULL); }
static void corgi_restart(char mode, const char *cmd) { if (!machine_is_corgi()) /* Green LED on tells the bootloader to reboot */ gpio_set_value(CORGI_GPIO_LED_GREEN, 1); arm_machine_restart('h', cmd); }
static void __init fixup_corgi(struct tag *tags, char **cmdline) { sharpsl_save_param(); if (machine_is_corgi()) memblock_add(0xa0000000, SZ_32M); else memblock_add(0xa0000000, SZ_64M); }
static void corgi_restart(enum reboot_mode mode, const char *cmd) { if (!machine_is_corgi()) /* Green LED on tells the bootloader to reboot */ gpio_set_value(CORGI_GPIO_LED_GREEN, 1); pxa_restart(REBOOT_HARD, cmd); }
static void corgi_restart(char mode) { RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; if (!machine_is_corgi()) /* Green LED on tells the bootloader to reboot */ set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); arm_machine_restart('h'); }
static void corgi_poweroff(void) { RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; if (!machine_is_corgi()) /* Green LED off tells the bootloader to halt */ reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); arm_machine_restart('h'); }
static void __init fixup_corgi(struct tag *tags, char **cmdline, struct meminfo *mi) { sharpsl_save_param(); mi->nr_banks=1; mi->bank[0].start = 0xa0000000; if (machine_is_corgi()) mi->bank[0].size = (32*1024*1024); else mi->bank[0].size = (64*1024*1024); }
static void __init fixup_corgi(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) { corgi_get_param(); mi->nr_banks=1; mi->bank[0].start = 0xa0000000; mi->bank[0].node = 0; if (machine_is_corgi()) mi->bank[0].size = (32*1024*1024); else mi->bank[0].size = (64*1024*1024); }
static int __devinit corgipm_init(void) { int ret; if (!machine_is_corgi() && !machine_is_shepherd() && !machine_is_husky()) return -ENODEV; corgipm_device = platform_device_alloc("sharpsl-pm", -1); if (!corgipm_device) return -ENOMEM; if (!machine_is_corgi()) corgi_pm_machinfo.batfull_irq = 1; corgipm_device->dev.platform_data = &corgi_pm_machinfo; ret = platform_device_add(corgipm_device); if (ret) platform_device_put(corgipm_device); return ret; }
static void corgi_charge(int on) { if (on) { if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) { GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); } else { GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); } } else { GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); } }
static void corgi_charge(int on) { if (on) { if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) { gpio_set_value(CORGI_GPIO_CHRG_ON, 0); gpio_set_value(CORGI_GPIO_CHRG_UKN, 1); } else { gpio_set_value(CORGI_GPIO_CHRG_ON, 1); gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); } } else { gpio_set_value(CORGI_GPIO_CHRG_ON, 0); gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); } }
int __init init_sharpsl(void) { struct mtd_partition *parts; int nb_parts = 0; char *part_type = "static"; printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); if (!sharpsl_map.virt) { printk("Failed to ioremap\n"); return -EIO; } simple_map_init(&sharpsl_map); mymtd = do_map_probe("map_rom", &sharpsl_map); if (!mymtd) { iounmap(sharpsl_map.virt); return -ENXIO; } mymtd->owner = THIS_MODULE; if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky() || machine_is_poodle()) { sharpsl_partitions[0].size=0x006d0000; sharpsl_partitions[0].offset=0x00120000; } else if (machine_is_tosa()) { sharpsl_partitions[0].size=0x006a0000; sharpsl_partitions[0].offset=0x00160000; } else if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) { sharpsl_partitions[0].size=0x006b0000; sharpsl_partitions[0].offset=0x00140000; } else { map_destroy(mymtd); iounmap(sharpsl_map.virt); return -ENODEV; } parts = sharpsl_partitions; nb_parts = ARRAY_SIZE(sharpsl_partitions); printk(KERN_NOTICE "Using %s partition definition\n", part_type); add_mtd_partitions(mymtd, parts, nb_parts); return 0; }
static void corgi_presuspend(void) { int i; unsigned long wakeup_mask; /* charging , so CHARGE_ON bit is HIGH during OFF. */ if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON)) PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON); else PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON); if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE)) PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE); else PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE); if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN)) PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN); else PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN); /* Resume on keyboard power key */ PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0); wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL); if (!machine_is_corgi()) wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW); PWER = wakeup_mask | PWER_RTC; PRER = wakeup_mask; PFER = wakeup_mask; for (i = 0; i <=15; i++) { if (PRER & PFER & GPIO_bit(i)) { if (GPLR0 & GPIO_bit(i) ) PRER &= ~GPIO_bit(i); else PFER &= ~GPIO_bit(i); } } }
static int __init corgi_init(void) { int ret; if (!(machine_is_corgi() || machine_is_shepherd() || machine_is_husky())) return -ENODEV; corgi_snd_device = platform_device_alloc("soc-audio", -1); if (!corgi_snd_device) return -ENOMEM; platform_set_drvdata(corgi_snd_device, &snd_soc_corgi); ret = platform_device_add(corgi_snd_device); if (ret) platform_device_put(corgi_snd_device); return ret; }
static int sharpsl_pm_remove(struct platform_device *pdev) { pm_set_ops(NULL); device_remove_file(&pdev->dev, &dev_attr_battery_percentage); device_remove_file(&pdev->dev, &dev_attr_battery_voltage); free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); if (sharpsl_pm.machinfo->gpio_fatal) free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); if (!machine_is_corgi()) free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); del_timer_sync(&sharpsl_pm.chrg_full_timer); del_timer_sync(&sharpsl_pm.ac_timer); return 0; }
static void __init corgi_init(void) { pm_power_off = corgi_poweroff; /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ PCFR |= PCFR_OPDE; pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config)); /* allow wakeup from various GPIOs */ gpio_set_wake(CORGI_GPIO_KEY_INT, 1); gpio_set_wake(CORGI_GPIO_WAKEUP, 1); gpio_set_wake(CORGI_GPIO_AC_IN, 1); gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1); if (!machine_is_corgi()) gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1); pxa_set_ffuart_info(NULL); pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); corgi_init_spi(); pxa_set_udc_info(&udc_info); pxa_set_mci_info(&corgi_mci_platform_data); pxa_set_ficp_info(&corgi_ficp_platform_data); pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(corgi_i2c_devices)); platform_scoop_config = &corgi_pcmcia_config; if (machine_is_husky()) sharpsl_nand_partitions[1].size = 53 * 1024 * 1024; platform_add_devices(devices, ARRAY_SIZE(devices)); regulator_has_full_constraints(); }
/* * Main initialization routine */ static int __init sharpsl_nand_init(void) { struct nand_chip *this; struct mtd_partition *sharpsl_partition_info; int err = 0; /* Allocate memory for MTD device structure and private data */ sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!sharpsl_mtd) { printk("Unable to allocate SharpSL NAND MTD device structure.\n"); return -ENOMEM; } /* map physical address */ sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); if (!sharpsl_io_base) { printk("ioremap to access Sharp SL NAND chip failed\n"); kfree(sharpsl_mtd); return -EIO; } /* Get pointer to private data */ this = (struct nand_chip *)(&sharpsl_mtd[1]); /* Initialize structures */ memset(sharpsl_mtd, 0, sizeof(struct mtd_info)); memset(this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ sharpsl_mtd->priv = this; sharpsl_mtd->owner = THIS_MODULE; /* * PXA initialize */ writeb(readb(FLASHCTL) | FLWP, FLASHCTL); /* Set address of NAND IO lines */ this->IO_ADDR_R = FLASHIO; this->IO_ADDR_W = FLASHIO; /* Set address of hardware control function */ this->cmd_ctrl = sharpsl_nand_hwcontrol; this->dev_ready = sharpsl_nand_dev_ready; /* 15 us command delay time */ this->chip_delay = 15; /* set eccmode using hardware ECC */ this->ecc.mode = NAND_ECC_HW; this->ecc.size = 256; this->ecc.bytes = 3; this->badblock_pattern = &sharpsl_bbt; if (machine_is_akita() || machine_is_borzoi()) { this->badblock_pattern = &sharpsl_akita_bbt; this->ecc.layout = &akita_oobinfo; } this->ecc.hwctl = sharpsl_nand_enable_hwecc; this->ecc.calculate = sharpsl_nand_calculate_ecc; this->ecc.correct = nand_correct_data; /* Scan to find existence of the device */ err = nand_scan(sharpsl_mtd, 1); if (err) { iounmap(sharpsl_io_base); kfree(sharpsl_mtd); return err; } /* Register the partitions */ sharpsl_mtd->name = "sharpsl-nand"; nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, &sharpsl_partition_info, 0); if (nr_partitions <= 0) { nr_partitions = DEFAULT_NUM_PARTITIONS; sharpsl_partition_info = sharpsl_nand_default_partition_info; if (machine_is_poodle()) { sharpsl_partition_info[1].size = 22 * 1024 * 1024; } else if (machine_is_corgi() || machine_is_shepherd()) { sharpsl_partition_info[1].size = 25 * 1024 * 1024; } else if (machine_is_husky()) { sharpsl_partition_info[1].size = 53 * 1024 * 1024; } else if (machine_is_spitz()) { sharpsl_partition_info[1].size = 5 * 1024 * 1024; } else if (machine_is_akita()) { sharpsl_partition_info[1].size = 58 * 1024 * 1024; } else if (machine_is_borzoi()) { sharpsl_partition_info[1].size = 32 * 1024 * 1024; } } add_mtd_partitions(sharpsl_mtd, sharpsl_partition_info, nr_partitions); /* Return happy */ return 0; }
static void sharpsl_battery_thread(void *private_) { int voltage, percent, apm_status, i = 0; if (!sharpsl_pm.machinfo) return; sharpsl_pm.battstat.ac_status = (STATUS_AC_IN() ? APM_AC_ONLINE : APM_AC_OFFLINE); /* Corgi cannot confirm when battery fully charged so periodically kick! */ if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON) && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) schedule_work(&toggle_charger); while(1) { voltage = sharpsl_read_main_battery(); if (voltage > 0) break; if (i++ > 5) { voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n"); break; } } voltage = sharpsl_average_value(voltage); apm_status = get_apm_status(voltage); percent = get_percentage(voltage); /* At low battery voltages, the voltage has a tendency to start creeping back up so we try to avoid this here */ if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) { sharpsl_pm.battstat.mainbat_voltage = voltage; sharpsl_pm.battstat.mainbat_status = apm_status; sharpsl_pm.battstat.mainbat_percent = percent; } dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage, sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); /* If battery is low. limit backlight intensity to save power. */ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) || (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) { if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) { corgibl_limit_intensity(1); sharpsl_pm.flags |= SHARPSL_BL_LIMIT; } } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) { corgibl_limit_intensity(0); sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT; } /* Suspend if critical battery level */ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL) && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) { sharpsl_pm.flags |= SHARPSL_APM_QUEUED; dev_err(sharpsl_pm.dev, "Fatal Off\n"); apm_queue_event(APM_CRITICAL_SUSPEND); } schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME); }