Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'pxa-tosa' into pxa

Conflicts:

arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/spitz.c

authored by

Russell King and committed by
Russell King
7fecc34e a9da4f7e

+1540 -98
+2
MAINTAINERS
··· 584 584 S: Maintained 585 585 586 586 ARM/TOSA MACHINE SUPPORT 587 + P: Dmitry Baryshkov 588 + M: dbaryshkov@gmail.com 587 589 P: Dirk Opfer 588 590 M: dirk@opfer-online.de 589 591 S: Maintained
+9
arch/arm/mach-pxa/Kconfig
··· 310 310 default BACKLIGHT_PWM 311 311 help 312 312 Enable support for PXA2xx/PXA3xx PWM controllers 313 + 314 + config TOSA_BT 315 + tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" 316 + depends on MACH_TOSA 317 + select RFKILL 318 + help 319 + This is a simple driver that is able to control 320 + the state of built in bluetooth chip on tosa. 321 + 313 322 endif
+3 -1
arch/arm/mach-pxa/Makefile
··· 4 4 5 5 # Common support (must be linked before board specific support) 6 6 obj-y += clock.o devices.o generic.o irq.o dma.o \ 7 - time.o gpio.o 7 + time.o gpio.o reset.o 8 8 obj-$(CONFIG_PM) += pm.o sleep.o standby.o 9 9 obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o 10 10 ··· 61 61 ifeq ($(CONFIG_PCI),y) 62 62 obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o 63 63 endif 64 + 65 + obj-$(CONFIG_TOSA_BT) += tosa-bt.o
+96
arch/arm/mach-pxa/reset.c
··· 1 + /* 2 + * This program is free software; you can redistribute it and/or modify 3 + * it under the terms of the GNU General Public License version 2 as 4 + * published by the Free Software Foundation. 5 + */ 6 + #include <linux/kernel.h> 7 + #include <linux/module.h> 8 + #include <linux/delay.h> 9 + #include <linux/gpio.h> 10 + #include <asm/io.h> 11 + #include <asm/proc-fns.h> 12 + 13 + #include <asm/arch/pxa-regs.h> 14 + #include <asm/arch/pxa2xx-regs.h> 15 + 16 + static void do_hw_reset(void); 17 + 18 + static int reset_gpio = -1; 19 + 20 + int init_gpio_reset(int gpio) 21 + { 22 + int rc; 23 + 24 + rc = gpio_request(gpio, "reset generator"); 25 + if (rc) { 26 + printk(KERN_ERR "Can't request reset_gpio\n"); 27 + goto out; 28 + } 29 + 30 + rc = gpio_direction_input(gpio); 31 + if (rc) { 32 + printk(KERN_ERR "Can't configure reset_gpio for input\n"); 33 + gpio_free(gpio); 34 + goto out; 35 + } 36 + 37 + out: 38 + if (!rc) 39 + reset_gpio = gpio; 40 + 41 + return rc; 42 + } 43 + 44 + /* 45 + * Trigger GPIO reset. 46 + * This covers various types of logic connecting gpio pin 47 + * to RESET pins (nRESET or GPIO_RESET): 48 + */ 49 + static void do_gpio_reset(void) 50 + { 51 + BUG_ON(reset_gpio == -1); 52 + 53 + /* drive it low */ 54 + gpio_direction_output(reset_gpio, 0); 55 + mdelay(2); 56 + /* rising edge or drive high */ 57 + gpio_set_value(reset_gpio, 1); 58 + mdelay(2); 59 + /* falling edge */ 60 + gpio_set_value(reset_gpio, 0); 61 + 62 + /* give it some time */ 63 + mdelay(10); 64 + 65 + WARN_ON(1); 66 + /* fallback */ 67 + do_hw_reset(); 68 + } 69 + 70 + static void do_hw_reset(void) 71 + { 72 + /* Initialize the watchdog and let it fire */ 73 + OWER = OWER_WME; 74 + OSSR = OSSR_M3; 75 + OSMR3 = OSCR + 368640; /* ... in 100 ms */ 76 + } 77 + 78 + void arch_reset(char mode) 79 + { 80 + if (cpu_is_pxa2xx()) 81 + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; 82 + 83 + switch (mode) { 84 + case 's': 85 + /* Jump into ROM at address 0 */ 86 + cpu_reset(0); 87 + break; 88 + case 'h': 89 + do_hw_reset(); 90 + break; 91 + case 'g': 92 + do_gpio_reset(); 93 + break; 94 + } 95 + } 96 +
+3 -5
arch/arm/mach-pxa/spitz.c
··· 38 38 #include <asm/arch/pxa-regs.h> 39 39 #include <asm/arch/pxa2xx-regs.h> 40 40 #include <asm/arch/pxa2xx-gpio.h> 41 + #include <asm/arch/pxa27x-udc.h> 41 42 #include <asm/arch/irda.h> 42 43 #include <asm/arch/mmc.h> 43 44 #include <asm/arch/ohci.h> ··· 530 529 531 530 static void spitz_poweroff(void) 532 531 { 533 - pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT); 534 - GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET); 535 - 536 - mdelay(1000); 537 - arm_machine_restart('h'); 532 + arm_machine_restart('g'); 538 533 } 539 534 540 535 static void spitz_restart(char mode) ··· 544 547 545 548 static void __init common_init(void) 546 549 { 550 + init_gpio_reset(SPITZ_GPIO_ON_RESET); 547 551 pm_power_off = spitz_poweroff; 548 552 arm_pm_restart = spitz_restart; 549 553
+150
arch/arm/mach-pxa/tosa-bt.c
··· 1 + /* 2 + * Bluetooth built-in chip control 3 + * 4 + * Copyright (c) 2008 Dmitry Baryshkov 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + */ 11 + 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/gpio.h> 16 + #include <linux/delay.h> 17 + #include <linux/rfkill.h> 18 + 19 + #include <asm/arch/tosa_bt.h> 20 + 21 + static void tosa_bt_on(struct tosa_bt_data *data) 22 + { 23 + gpio_set_value(data->gpio_reset, 0); 24 + gpio_set_value(data->gpio_pwr, 1); 25 + gpio_set_value(data->gpio_reset, 1); 26 + mdelay(20); 27 + gpio_set_value(data->gpio_reset, 0); 28 + } 29 + 30 + static void tosa_bt_off(struct tosa_bt_data *data) 31 + { 32 + gpio_set_value(data->gpio_reset, 1); 33 + mdelay(10); 34 + gpio_set_value(data->gpio_pwr, 0); 35 + gpio_set_value(data->gpio_reset, 0); 36 + } 37 + 38 + static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) 39 + { 40 + pr_info("BT_RADIO going: %s\n", 41 + state == RFKILL_STATE_ON ? "on" : "off"); 42 + 43 + if (state == RFKILL_STATE_ON) { 44 + pr_info("TOSA_BT: going ON\n"); 45 + tosa_bt_on(data); 46 + } else { 47 + pr_info("TOSA_BT: going OFF\n"); 48 + tosa_bt_off(data); 49 + } 50 + return 0; 51 + } 52 + 53 + static int tosa_bt_probe(struct platform_device *dev) 54 + { 55 + int rc; 56 + struct rfkill *rfk; 57 + 58 + struct tosa_bt_data *data = dev->dev.platform_data; 59 + 60 + rc = gpio_request(data->gpio_reset, "Bluetooth reset"); 61 + if (rc) 62 + goto err_reset; 63 + rc = gpio_direction_output(data->gpio_reset, 0); 64 + if (rc) 65 + goto err_reset_dir; 66 + rc = gpio_request(data->gpio_pwr, "Bluetooth power"); 67 + if (rc) 68 + goto err_pwr; 69 + rc = gpio_direction_output(data->gpio_pwr, 0); 70 + if (rc) 71 + goto err_pwr_dir; 72 + 73 + rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); 74 + if (!rfk) { 75 + rc = -ENOMEM; 76 + goto err_rfk_alloc; 77 + } 78 + 79 + rfk->name = "tosa-bt"; 80 + rfk->toggle_radio = tosa_bt_toggle_radio; 81 + rfk->data = data; 82 + #ifdef CONFIG_RFKILL_LEDS 83 + rfk->led_trigger.name = "tosa-bt"; 84 + #endif 85 + 86 + rc = rfkill_register(rfk); 87 + if (rc) 88 + goto err_rfkill; 89 + 90 + platform_set_drvdata(dev, rfk); 91 + 92 + return 0; 93 + 94 + err_rfkill: 95 + if (rfk) 96 + rfkill_free(rfk); 97 + rfk = NULL; 98 + err_rfk_alloc: 99 + tosa_bt_off(data); 100 + err_pwr_dir: 101 + gpio_free(data->gpio_pwr); 102 + err_pwr: 103 + err_reset_dir: 104 + gpio_free(data->gpio_reset); 105 + err_reset: 106 + return rc; 107 + } 108 + 109 + static int __devexit tosa_bt_remove(struct platform_device *dev) 110 + { 111 + struct tosa_bt_data *data = dev->dev.platform_data; 112 + struct rfkill *rfk = platform_get_drvdata(dev); 113 + 114 + platform_set_drvdata(dev, NULL); 115 + 116 + if (rfk) 117 + rfkill_unregister(rfk); 118 + rfk = NULL; 119 + 120 + tosa_bt_off(data); 121 + 122 + gpio_free(data->gpio_pwr); 123 + gpio_free(data->gpio_reset); 124 + 125 + return 0; 126 + } 127 + 128 + static struct platform_driver tosa_bt_driver = { 129 + .probe = tosa_bt_probe, 130 + .remove = __devexit_p(tosa_bt_remove), 131 + 132 + .driver = { 133 + .name = "tosa-bt", 134 + .owner = THIS_MODULE, 135 + }, 136 + }; 137 + 138 + 139 + static int __init tosa_bt_init(void) 140 + { 141 + return platform_driver_register(&tosa_bt_driver); 142 + } 143 + 144 + static void __exit tosa_bt_exit(void) 145 + { 146 + platform_driver_unregister(&tosa_bt_driver); 147 + } 148 + 149 + module_init(tosa_bt_init); 150 + module_exit(tosa_bt_exit);
+344 -48
arch/arm/mach-pxa/tosa.c
··· 18 18 #include <linux/major.h> 19 19 #include <linux/fs.h> 20 20 #include <linux/interrupt.h> 21 - #include <linux/mmc/host.h> 22 - #include <linux/pm.h> 23 21 #include <linux/delay.h> 22 + #include <linux/fb.h> 23 + #include <linux/mmc/host.h> 24 + #include <linux/mfd/tc6393xb.h> 25 + #include <linux/mfd/tmio.h> 26 + #include <linux/mtd/nand.h> 27 + #include <linux/mtd/partitions.h> 28 + #include <linux/pm.h> 24 29 #include <linux/gpio_keys.h> 25 30 #include <linux/input.h> 26 31 #include <linux/gpio.h> 32 + #include <linux/pda_power.h> 33 + #include <linux/rfkill.h> 27 34 28 35 #include <asm/setup.h> 29 - #include <asm/memory.h> 30 36 #include <asm/mach-types.h> 31 - #include <asm/hardware.h> 32 - #include <asm/irq.h> 33 - #include <asm/system.h> 34 - #include <asm/arch/pxa-regs.h> 35 37 #include <asm/arch/pxa2xx-regs.h> 36 38 #include <asm/arch/mfp-pxa25x.h> 37 39 #include <asm/arch/irda.h> 38 40 #include <asm/arch/i2c.h> 39 41 #include <asm/arch/mmc.h> 40 42 #include <asm/arch/udc.h> 43 + #include <asm/arch/tosa_bt.h> 41 44 42 45 #include <asm/mach/arch.h> 43 - #include <asm/mach/map.h> 44 - #include <asm/mach/irq.h> 45 46 #include <asm/arch/tosa.h> 46 47 47 48 #include <asm/hardware/scoop.h> ··· 87 86 GPIO6_MMC_CLK, 88 87 GPIO8_MMC_CS0, 89 88 GPIO9_GPIO, /* Detect */ 90 - // GPIO10 nSD_INT 89 + GPIO10_GPIO, /* nSD_INT */ 91 90 92 91 /* CF */ 93 92 GPIO13_GPIO, /* CD_IRQ */ ··· 125 124 GPIO44_BTUART_CTS, 126 125 GPIO45_BTUART_RTS, 127 126 128 - /* IrDA */ 129 - GPIO46_STUART_RXD, 130 - GPIO47_STUART_TXD, 131 - 132 127 /* Keybd */ 133 - GPIO58_GPIO, 134 - GPIO59_GPIO, 135 - GPIO60_GPIO, 136 - GPIO61_GPIO, 137 - GPIO62_GPIO, 138 - GPIO63_GPIO, 139 - GPIO64_GPIO, 140 - GPIO65_GPIO, 141 - GPIO66_GPIO, 142 - GPIO67_GPIO, 143 - GPIO68_GPIO, 144 - GPIO69_GPIO, 145 - GPIO70_GPIO, 146 - GPIO71_GPIO, 147 - GPIO72_GPIO, 148 - GPIO73_GPIO, 149 - GPIO74_GPIO, 150 - GPIO75_GPIO, 128 + GPIO58_GPIO | MFP_LPM_DRIVE_LOW, 129 + GPIO59_GPIO | MFP_LPM_DRIVE_LOW, 130 + GPIO60_GPIO | MFP_LPM_DRIVE_LOW, 131 + GPIO61_GPIO | MFP_LPM_DRIVE_LOW, 132 + GPIO62_GPIO | MFP_LPM_DRIVE_LOW, 133 + GPIO63_GPIO | MFP_LPM_DRIVE_LOW, 134 + GPIO64_GPIO | MFP_LPM_DRIVE_LOW, 135 + GPIO65_GPIO | MFP_LPM_DRIVE_LOW, 136 + GPIO66_GPIO | MFP_LPM_DRIVE_LOW, 137 + GPIO67_GPIO | MFP_LPM_DRIVE_LOW, 138 + GPIO68_GPIO | MFP_LPM_DRIVE_LOW, 139 + GPIO69_GPIO | MFP_LPM_DRIVE_LOW, 140 + GPIO70_GPIO | MFP_LPM_DRIVE_LOW, 141 + GPIO71_GPIO | MFP_LPM_DRIVE_LOW, 142 + GPIO72_GPIO | MFP_LPM_DRIVE_LOW, 143 + GPIO73_GPIO | MFP_LPM_DRIVE_LOW, 144 + GPIO74_GPIO | MFP_LPM_DRIVE_LOW, 145 + GPIO75_GPIO | MFP_LPM_DRIVE_LOW, 151 146 152 147 /* SPI */ 153 148 GPIO81_SSP2_CLK_OUT, 154 149 GPIO82_SSP2_FRM_OUT, 155 150 GPIO83_SSP2_TXD, 156 151 }; 152 + 153 + static unsigned long tosa_pin_irda_off[] = { 154 + GPIO46_STUART_RXD, 155 + GPIO47_GPIO | MFP_LPM_DRIVE_LOW, 156 + }; 157 + 158 + static unsigned long tosa_pin_irda_on[] = { 159 + GPIO46_STUART_RXD, 160 + GPIO47_STUART_TXD, 161 + }; 162 + 157 163 158 164 /* 159 165 * SCOOP Device ··· 257 249 258 250 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); 259 251 252 + err = gpio_request(TOSA_GPIO_nSD_DETECT, "MMC/SD card detect"); 253 + if (err) { 254 + printk(KERN_ERR "tosa_mci_init: can't request nSD_DETECT gpio\n"); 255 + goto err_gpio_detect; 256 + } 257 + err = gpio_direction_input(TOSA_GPIO_nSD_DETECT); 258 + if (err) 259 + goto err_gpio_detect_dir; 260 + 260 261 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, 261 262 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 262 263 "MMC/SD card detect", data); ··· 274 257 goto err_irq; 275 258 } 276 259 277 - err = gpio_request(TOSA_GPIO_SD_WP, "sd_wp"); 260 + err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect"); 278 261 if (err) { 279 262 printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n"); 280 263 goto err_gpio_wp; ··· 283 266 if (err) 284 267 goto err_gpio_wp_dir; 285 268 286 - err = gpio_request(TOSA_GPIO_PWR_ON, "sd_pwr"); 269 + err = gpio_request(TOSA_GPIO_PWR_ON, "SD Power"); 287 270 if (err) { 288 271 printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); 289 272 goto err_gpio_pwr; ··· 292 275 if (err) 293 276 goto err_gpio_pwr_dir; 294 277 278 + err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int"); 279 + if (err) { 280 + printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); 281 + goto err_gpio_int; 282 + } 283 + err = gpio_direction_input(TOSA_GPIO_nSD_INT); 284 + if (err) 285 + goto err_gpio_int_dir; 286 + 295 287 return 0; 296 288 289 + err_gpio_int_dir: 290 + gpio_free(TOSA_GPIO_nSD_INT); 291 + err_gpio_int: 297 292 err_gpio_pwr_dir: 298 293 gpio_free(TOSA_GPIO_PWR_ON); 299 294 err_gpio_pwr: ··· 314 285 err_gpio_wp: 315 286 free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); 316 287 err_irq: 288 + err_gpio_detect_dir: 289 + gpio_free(TOSA_GPIO_nSD_DETECT); 290 + err_gpio_detect: 317 291 return err; 318 292 } 319 293 ··· 338 306 339 307 static void tosa_mci_exit(struct device *dev, void *data) 340 308 { 309 + gpio_free(TOSA_GPIO_nSD_INT); 341 310 gpio_free(TOSA_GPIO_PWR_ON); 342 311 gpio_free(TOSA_GPIO_SD_WP); 343 312 free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); 313 + gpio_free(TOSA_GPIO_nSD_DETECT); 344 314 } 345 315 346 316 static struct pxamci_platform_data tosa_mci_platform_data = { ··· 356 322 /* 357 323 * Irda 358 324 */ 325 + static void tosa_irda_transceiver_mode(struct device *dev, int mode) 326 + { 327 + if (mode & IR_OFF) { 328 + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0); 329 + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); 330 + gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); 331 + } else { 332 + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_on)); 333 + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1); 334 + } 335 + } 336 + 359 337 static int tosa_irda_startup(struct device *dev) 360 338 { 361 339 int ret; 362 340 341 + ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX"); 342 + if (ret) 343 + goto err_tx; 344 + ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); 345 + if (ret) 346 + goto err_tx_dir; 347 + 363 348 ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); 364 349 if (ret) 365 - return ret; 350 + goto err_pwr; 366 351 367 352 ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); 368 353 if (ret) 369 - gpio_free(TOSA_GPIO_IR_POWERDWN); 354 + goto err_pwr_dir; 370 355 356 + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); 357 + 358 + return 0; 359 + 360 + err_pwr_dir: 361 + gpio_free(TOSA_GPIO_IR_POWERDWN); 362 + err_pwr: 363 + err_tx_dir: 364 + gpio_free(TOSA_GPIO_IRDA_TX); 365 + err_tx: 371 366 return ret; 372 - } 367 + } 373 368 374 369 static void tosa_irda_shutdown(struct device *dev) 375 370 { 371 + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); 376 372 gpio_free(TOSA_GPIO_IR_POWERDWN); 377 - } 378 - 379 - static void tosa_irda_transceiver_mode(struct device *dev, int mode) 380 - { 381 - gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF)); 373 + gpio_free(TOSA_GPIO_IRDA_TX); 382 374 } 383 375 384 376 static struct pxaficp_platform_data tosa_ficp_platform_data = { ··· 412 352 .transceiver_mode = tosa_irda_transceiver_mode, 413 353 .startup = tosa_irda_startup, 414 354 .shutdown = tosa_irda_shutdown, 355 + }; 356 + 357 + /* 358 + * Tosa AC IN 359 + */ 360 + static int tosa_power_init(struct device *dev) 361 + { 362 + int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in"); 363 + if (ret) 364 + goto err_gpio_req; 365 + 366 + ret = gpio_direction_input(TOSA_GPIO_AC_IN); 367 + if (ret) 368 + goto err_gpio_in; 369 + 370 + return 0; 371 + 372 + err_gpio_in: 373 + gpio_free(TOSA_GPIO_AC_IN); 374 + err_gpio_req: 375 + return ret; 376 + } 377 + 378 + static void tosa_power_exit(struct device *dev) 379 + { 380 + gpio_free(TOSA_GPIO_AC_IN); 381 + } 382 + 383 + static int tosa_power_ac_online(void) 384 + { 385 + return gpio_get_value(TOSA_GPIO_AC_IN) == 0; 386 + } 387 + 388 + static char *tosa_ac_supplied_to[] = { 389 + "main-battery", 390 + "backup-battery", 391 + "jacket-battery", 392 + }; 393 + 394 + static struct pda_power_pdata tosa_power_data = { 395 + .init = tosa_power_init, 396 + .is_ac_online = tosa_power_ac_online, 397 + .exit = tosa_power_exit, 398 + .supplied_to = tosa_ac_supplied_to, 399 + .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), 400 + }; 401 + 402 + static struct resource tosa_power_resource[] = { 403 + { 404 + .name = "ac", 405 + .start = gpio_to_irq(TOSA_GPIO_AC_IN), 406 + .end = gpio_to_irq(TOSA_GPIO_AC_IN), 407 + .flags = IORESOURCE_IRQ | 408 + IORESOURCE_IRQ_HIGHEDGE | 409 + IORESOURCE_IRQ_LOWEDGE, 410 + }, 411 + }; 412 + 413 + static struct platform_device tosa_power_device = { 414 + .name = "pda-power", 415 + .id = -1, 416 + .dev.platform_data = &tosa_power_data, 417 + .resource = tosa_power_resource, 418 + .num_resources = ARRAY_SIZE(tosa_power_resource), 415 419 }; 416 420 417 421 /* ··· 563 439 }, 564 440 { 565 441 .name = "tosa:blue:bluetooth", 566 - .default_trigger = "none", 442 + .default_trigger = "tosa-bt", 567 443 .gpio = TOSA_GPIO_BT_LED, 568 444 }, 569 445 }; ··· 581 457 }, 582 458 }; 583 459 460 + /* 461 + * Toshiba Mobile IO Controller 462 + */ 463 + static struct resource tc6393xb_resources[] = { 464 + [0] = { 465 + .start = TOSA_LCDC_PHYS, 466 + .end = TOSA_LCDC_PHYS + 0x3ffffff, 467 + .flags = IORESOURCE_MEM, 468 + }, 469 + 470 + [1] = { 471 + .start = TOSA_IRQ_GPIO_TC6393XB_INT, 472 + .end = TOSA_IRQ_GPIO_TC6393XB_INT, 473 + .flags = IORESOURCE_IRQ, 474 + }, 475 + }; 476 + 477 + 478 + static int tosa_tc6393xb_enable(struct platform_device *dev) 479 + { 480 + int rc; 481 + 482 + rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr"); 483 + if (rc) 484 + goto err_req_pclr; 485 + rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); 486 + if (rc) 487 + goto err_req_suspend; 488 + rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v"); 489 + if (rc) 490 + goto err_req_l3v; 491 + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); 492 + if (rc) 493 + goto err_dir_l3v; 494 + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0); 495 + if (rc) 496 + goto err_dir_suspend; 497 + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0); 498 + if (rc) 499 + goto err_dir_pclr; 500 + 501 + mdelay(1); 502 + 503 + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); 504 + 505 + mdelay(10); 506 + 507 + gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1); 508 + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); 509 + 510 + return 0; 511 + err_dir_pclr: 512 + err_dir_suspend: 513 + err_dir_l3v: 514 + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); 515 + err_req_l3v: 516 + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); 517 + err_req_suspend: 518 + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); 519 + err_req_pclr: 520 + return rc; 521 + } 522 + 523 + static int tosa_tc6393xb_disable(struct platform_device *dev) 524 + { 525 + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); 526 + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); 527 + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); 528 + 529 + return 0; 530 + } 531 + 532 + static int tosa_tc6393xb_resume(struct platform_device *dev) 533 + { 534 + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); 535 + mdelay(10); 536 + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); 537 + mdelay(10); 538 + 539 + return 0; 540 + } 541 + 542 + static int tosa_tc6393xb_suspend(struct platform_device *dev) 543 + { 544 + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0); 545 + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0); 546 + return 0; 547 + } 548 + 549 + static struct mtd_partition tosa_nand_partition[] = { 550 + { 551 + .name = "smf", 552 + .offset = 0, 553 + .size = 7 * 1024 * 1024, 554 + }, 555 + { 556 + .name = "root", 557 + .offset = MTDPART_OFS_APPEND, 558 + .size = 28 * 1024 * 1024, 559 + }, 560 + { 561 + .name = "home", 562 + .offset = MTDPART_OFS_APPEND, 563 + .size = MTDPART_SIZ_FULL, 564 + }, 565 + }; 566 + 567 + static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 568 + 569 + static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = { 570 + .options = 0, 571 + .offs = 4, 572 + .len = 2, 573 + .pattern = scan_ff_pattern 574 + }; 575 + 576 + static struct tmio_nand_data tosa_tc6393xb_nand_config = { 577 + .num_partitions = ARRAY_SIZE(tosa_nand_partition), 578 + .partition = tosa_nand_partition, 579 + .badblock_pattern = &tosa_tc6393xb_nand_bbt, 580 + }; 581 + 582 + static struct tc6393xb_platform_data tosa_tc6393xb_setup = { 583 + .scr_pll2cr = 0x0cc1, 584 + .scr_gper = 0x3300, 585 + .scr_gpo_dsr = 586 + TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), 587 + .scr_gpo_doecr = 588 + TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), 589 + 590 + .irq_base = IRQ_BOARD_START, 591 + .gpio_base = TOSA_TC6393XB_GPIO_BASE, 592 + 593 + .enable = tosa_tc6393xb_enable, 594 + .disable = tosa_tc6393xb_disable, 595 + .suspend = tosa_tc6393xb_suspend, 596 + .resume = tosa_tc6393xb_resume, 597 + 598 + .nand_data = &tosa_tc6393xb_nand_config, 599 + }; 600 + 601 + 602 + static struct platform_device tc6393xb_device = { 603 + .name = "tc6393xb", 604 + .id = -1, 605 + .dev = { 606 + .platform_data = &tosa_tc6393xb_setup, 607 + }, 608 + .num_resources = ARRAY_SIZE(tc6393xb_resources), 609 + .resource = tc6393xb_resources, 610 + }; 611 + 612 + static struct tosa_bt_data tosa_bt_data = { 613 + .gpio_pwr = TOSA_GPIO_BT_PWR_EN, 614 + .gpio_reset = TOSA_GPIO_BT_RESET, 615 + }; 616 + 617 + static struct platform_device tosa_bt_device = { 618 + .name = "tosa-bt", 619 + .id = -1, 620 + .dev.platform_data = &tosa_bt_data, 621 + }; 622 + 623 + 584 624 static struct platform_device *devices[] __initdata = { 585 625 &tosascoop_device, 586 626 &tosascoop_jc_device, 627 + &tc6393xb_device, 628 + &tosa_power_device, 587 629 &tosakbd_device, 588 630 &tosa_gpio_keys_device, 589 631 &tosaled_device, 632 + &tosa_bt_device, 590 633 }; 591 634 592 635 static void tosa_poweroff(void) 593 636 { 594 - gpio_direction_output(TOSA_GPIO_ON_RESET, 0); 595 - gpio_set_value(TOSA_GPIO_ON_RESET, 1); 596 - 597 - mdelay(1000); 598 - arm_machine_restart('h'); 637 + arm_machine_restart('g'); 599 638 } 600 639 601 640 static void tosa_restart(char mode) ··· 772 485 773 486 static void __init tosa_init(void) 774 487 { 488 + int dummy; 489 + 775 490 pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); 491 + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); 776 492 gpio_set_wake(MFP_PIN_GPIO1, 1); 777 493 /* We can't pass to gpio-keys since it will drop the Reset altfunc */ 494 + 495 + init_gpio_reset(TOSA_GPIO_ON_RESET); 778 496 779 497 pm_power_off = tosa_poweroff; 780 498 arm_pm_restart = tosa_restart; ··· 788 496 789 497 /* enable batt_fault */ 790 498 PMCR = 0x01; 499 + 500 + dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12); 501 + dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12); 502 + dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); 791 503 792 504 pxa_set_mci_info(&tosa_mci_platform_data); 793 505 pxa_set_udc_info(&udc_info);
-2
drivers/input/keyboard/tosakbd.c
··· 215 215 unsigned long flags; 216 216 217 217 spin_lock_irqsave(&tosakbd->lock, flags); 218 - PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT); 219 - PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT); 220 218 tosakbd->suspended = 1; 221 219 spin_unlock_irqrestore(&tosakbd->lock, flags); 222 220
+11
drivers/mfd/Kconfig
··· 5 5 menu "Multifunction device drivers" 6 6 depends on HAS_IOMEM 7 7 8 + config MFD_CORE 9 + tristate 10 + default n 11 + 8 12 config MFD_SM501 9 13 tristate "Support for Silicon Motion SM501" 10 14 ---help--- ··· 41 37 chips labeled "AIC2" and "AIC3", found on HTC Blueangel and 42 38 HTC Magician devices, respectively. Actual functionality is 43 39 handled by the leds-pasic3 and ds1wm drivers. 40 + 41 + config MFD_TC6393XB 42 + bool "Support Toshiba TC6393XB" 43 + depends on HAVE_GPIO_LIB 44 + select MFD_CORE 45 + help 46 + Support for Toshiba Mobile IO Controller TC6393XB 44 47 45 48 endmenu 46 49
+4
drivers/mfd/Makefile
··· 8 8 obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 9 9 obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 10 10 11 + obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o 12 + 13 + obj-$(CONFIG_MFD_CORE) += mfd-core.o 14 + 11 15 obj-$(CONFIG_MCP) += mcp-core.o 12 16 obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o 13 17 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+114
drivers/mfd/mfd-core.c
··· 1 + /* 2 + * drivers/mfd/mfd-core.c 3 + * 4 + * core MFD support 5 + * Copyright (c) 2006 Ian Molton 6 + * Copyright (c) 2007,2008 Dmitry Baryshkov 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + */ 13 + 14 + #include <linux/kernel.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/mfd/core.h> 17 + 18 + static int mfd_add_device(struct platform_device *parent, 19 + const struct mfd_cell *cell, 20 + struct resource *mem_base, 21 + int irq_base) 22 + { 23 + struct resource res[cell->num_resources]; 24 + struct platform_device *pdev; 25 + int ret = -ENOMEM; 26 + int r; 27 + 28 + pdev = platform_device_alloc(cell->name, parent->id); 29 + if (!pdev) 30 + goto fail_alloc; 31 + 32 + pdev->dev.parent = &parent->dev; 33 + 34 + ret = platform_device_add_data(pdev, 35 + cell, sizeof(struct mfd_cell)); 36 + if (ret) 37 + goto fail_device; 38 + 39 + memzero(res, sizeof(res)); 40 + for (r = 0; r < cell->num_resources; r++) { 41 + res[r].name = cell->resources[r].name; 42 + res[r].flags = cell->resources[r].flags; 43 + 44 + /* Find out base to use */ 45 + if (cell->resources[r].flags & IORESOURCE_MEM) { 46 + res[r].parent = mem_base; 47 + res[r].start = mem_base->start + 48 + cell->resources[r].start; 49 + res[r].end = mem_base->start + 50 + cell->resources[r].end; 51 + } else if (cell->resources[r].flags & IORESOURCE_IRQ) { 52 + res[r].start = irq_base + 53 + cell->resources[r].start; 54 + res[r].end = irq_base + 55 + cell->resources[r].end; 56 + } else { 57 + res[r].parent = cell->resources[r].parent; 58 + res[r].start = cell->resources[r].start; 59 + res[r].end = cell->resources[r].end; 60 + } 61 + } 62 + 63 + platform_device_add_resources(pdev, res, cell->num_resources); 64 + 65 + ret = platform_device_add(pdev); 66 + if (ret) 67 + goto fail_device; 68 + 69 + return 0; 70 + 71 + /* platform_device_del(pdev); */ 72 + fail_device: 73 + platform_device_put(pdev); 74 + fail_alloc: 75 + return ret; 76 + } 77 + 78 + int mfd_add_devices( 79 + struct platform_device *parent, 80 + const struct mfd_cell *cells, int n_devs, 81 + struct resource *mem_base, 82 + int irq_base) 83 + { 84 + int i; 85 + int ret = 0; 86 + 87 + for (i = 0; i < n_devs; i++) { 88 + ret = mfd_add_device(parent, cells + i, mem_base, irq_base); 89 + if (ret) 90 + break; 91 + } 92 + 93 + if (ret) 94 + mfd_remove_devices(parent); 95 + 96 + return ret; 97 + } 98 + EXPORT_SYMBOL(mfd_add_devices); 99 + 100 + static int mfd_remove_devices_fn(struct device *dev, void *unused) 101 + { 102 + platform_device_unregister( 103 + container_of(dev, struct platform_device, dev)); 104 + return 0; 105 + } 106 + 107 + void mfd_remove_devices(struct platform_device *parent) 108 + { 109 + device_for_each_child(&parent->dev, NULL, mfd_remove_devices_fn); 110 + } 111 + EXPORT_SYMBOL(mfd_remove_devices); 112 + 113 + MODULE_LICENSE("GPL"); 114 + MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
+600
drivers/mfd/tc6393xb.c
··· 1 + /* 2 + * Toshiba TC6393XB SoC support 3 + * 4 + * Copyright(c) 2005-2006 Chris Humbert 5 + * Copyright(c) 2005 Dirk Opfer 6 + * Copyright(c) 2005 Ian Molton <spyro@f2s.com> 7 + * Copyright(c) 2007 Dmitry Baryshkov 8 + * 9 + * Based on code written by Sharp/Lineo for 2.4 kernels 10 + * Based on locomo.c 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License version 2 as 14 + * published by the Free Software Foundation. 15 + */ 16 + 17 + #include <linux/kernel.h> 18 + #include <linux/module.h> 19 + #include <linux/io.h> 20 + #include <linux/irq.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/fb.h> 23 + #include <linux/clk.h> 24 + #include <linux/mfd/core.h> 25 + #include <linux/mfd/tmio.h> 26 + #include <linux/mfd/tc6393xb.h> 27 + #include <linux/gpio.h> 28 + 29 + #define SCR_REVID 0x08 /* b Revision ID */ 30 + #define SCR_ISR 0x50 /* b Interrupt Status */ 31 + #define SCR_IMR 0x52 /* b Interrupt Mask */ 32 + #define SCR_IRR 0x54 /* b Interrupt Routing */ 33 + #define SCR_GPER 0x60 /* w GP Enable */ 34 + #define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */ 35 + #define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */ 36 + #define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */ 37 + #define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */ 38 + #define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */ 39 + #define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */ 40 + #define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */ 41 + #define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */ 42 + #define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */ 43 + #define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */ 44 + #define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */ 45 + #define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */ 46 + #define SCR_CCR 0x98 /* w Clock Control */ 47 + #define SCR_PLL2CR 0x9a /* w PLL2 Control */ 48 + #define SCR_PLL1CR 0x9c /* l PLL1 Control */ 49 + #define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */ 50 + #define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */ 51 + #define SCR_FER 0xe0 /* b Function Enable */ 52 + #define SCR_MCR 0xe4 /* w Mode Control */ 53 + #define SCR_CONFIG 0xfc /* b Configuration Control */ 54 + #define SCR_DEBUG 0xff /* b Debug */ 55 + 56 + #define SCR_CCR_CK32K BIT(0) 57 + #define SCR_CCR_USBCK BIT(1) 58 + #define SCR_CCR_UNK1 BIT(4) 59 + #define SCR_CCR_MCLK_MASK (7 << 8) 60 + #define SCR_CCR_MCLK_OFF (0 << 8) 61 + #define SCR_CCR_MCLK_12 (1 << 8) 62 + #define SCR_CCR_MCLK_24 (2 << 8) 63 + #define SCR_CCR_MCLK_48 (3 << 8) 64 + #define SCR_CCR_HCLK_MASK (3 << 12) 65 + #define SCR_CCR_HCLK_24 (0 << 12) 66 + #define SCR_CCR_HCLK_48 (1 << 12) 67 + 68 + #define SCR_FER_USBEN BIT(0) /* USB host enable */ 69 + #define SCR_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */ 70 + #define SCR_FER_SLCDEN BIT(2) /* SLCD enable */ 71 + 72 + #define SCR_MCR_RDY_MASK (3 << 0) 73 + #define SCR_MCR_RDY_OPENDRAIN (0 << 0) 74 + #define SCR_MCR_RDY_TRISTATE (1 << 0) 75 + #define SCR_MCR_RDY_PUSHPULL (2 << 0) 76 + #define SCR_MCR_RDY_UNK BIT(2) 77 + #define SCR_MCR_RDY_EN BIT(3) 78 + #define SCR_MCR_INT_MASK (3 << 4) 79 + #define SCR_MCR_INT_OPENDRAIN (0 << 4) 80 + #define SCR_MCR_INT_TRISTATE (1 << 4) 81 + #define SCR_MCR_INT_PUSHPULL (2 << 4) 82 + #define SCR_MCR_INT_UNK BIT(6) 83 + #define SCR_MCR_INT_EN BIT(7) 84 + /* bits 8 - 16 are unknown */ 85 + 86 + #define TC_GPIO_BIT(i) (1 << (i & 0x7)) 87 + 88 + /*--------------------------------------------------------------------------*/ 89 + 90 + struct tc6393xb { 91 + void __iomem *scr; 92 + 93 + struct gpio_chip gpio; 94 + 95 + struct clk *clk; /* 3,6 Mhz */ 96 + 97 + spinlock_t lock; /* protects RMW cycles */ 98 + 99 + struct { 100 + u8 fer; 101 + u16 ccr; 102 + u8 gpi_bcr[3]; 103 + u8 gpo_dsr[3]; 104 + u8 gpo_doecr[3]; 105 + } suspend_state; 106 + 107 + struct resource rscr; 108 + struct resource *iomem; 109 + int irq; 110 + int irq_base; 111 + }; 112 + 113 + enum { 114 + TC6393XB_CELL_NAND, 115 + }; 116 + 117 + /*--------------------------------------------------------------------------*/ 118 + 119 + static int tc6393xb_nand_enable(struct platform_device *nand) 120 + { 121 + struct platform_device *dev = to_platform_device(nand->dev.parent); 122 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 123 + unsigned long flags; 124 + 125 + spin_lock_irqsave(&tc6393xb->lock, flags); 126 + 127 + /* SMD buffer on */ 128 + dev_dbg(&dev->dev, "SMD buffer on\n"); 129 + iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); 130 + 131 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 132 + 133 + return 0; 134 + } 135 + 136 + static struct resource __devinitdata tc6393xb_nand_resources[] = { 137 + { 138 + .name = TMIO_NAND_CONFIG, 139 + .start = 0x0100, 140 + .end = 0x01ff, 141 + .flags = IORESOURCE_MEM, 142 + }, 143 + { 144 + .name = TMIO_NAND_CONTROL, 145 + .start = 0x1000, 146 + .end = 0x1007, 147 + .flags = IORESOURCE_MEM, 148 + }, 149 + { 150 + .name = TMIO_NAND_IRQ, 151 + .start = IRQ_TC6393_NAND, 152 + .end = IRQ_TC6393_NAND, 153 + .flags = IORESOURCE_IRQ, 154 + }, 155 + }; 156 + 157 + static struct mfd_cell __devinitdata tc6393xb_cells[] = { 158 + [TC6393XB_CELL_NAND] = { 159 + .name = "tmio-nand", 160 + .enable = tc6393xb_nand_enable, 161 + .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), 162 + .resources = tc6393xb_nand_resources, 163 + }, 164 + }; 165 + 166 + /*--------------------------------------------------------------------------*/ 167 + 168 + static int tc6393xb_gpio_get(struct gpio_chip *chip, 169 + unsigned offset) 170 + { 171 + struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); 172 + 173 + /* XXX: does dsr also represent inputs? */ 174 + return ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) 175 + & TC_GPIO_BIT(offset); 176 + } 177 + 178 + static void __tc6393xb_gpio_set(struct gpio_chip *chip, 179 + unsigned offset, int value) 180 + { 181 + struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); 182 + u8 dsr; 183 + 184 + dsr = ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); 185 + if (value) 186 + dsr |= TC_GPIO_BIT(offset); 187 + else 188 + dsr &= ~TC_GPIO_BIT(offset); 189 + 190 + iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); 191 + } 192 + 193 + static void tc6393xb_gpio_set(struct gpio_chip *chip, 194 + unsigned offset, int value) 195 + { 196 + struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); 197 + unsigned long flags; 198 + 199 + spin_lock_irqsave(&tc6393xb->lock, flags); 200 + 201 + __tc6393xb_gpio_set(chip, offset, value); 202 + 203 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 204 + } 205 + 206 + static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, 207 + unsigned offset) 208 + { 209 + struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); 210 + unsigned long flags; 211 + u8 doecr; 212 + 213 + spin_lock_irqsave(&tc6393xb->lock, flags); 214 + 215 + doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 216 + doecr &= ~TC_GPIO_BIT(offset); 217 + iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 218 + 219 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 220 + 221 + return 0; 222 + } 223 + 224 + static int tc6393xb_gpio_direction_output(struct gpio_chip *chip, 225 + unsigned offset, int value) 226 + { 227 + struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); 228 + unsigned long flags; 229 + u8 doecr; 230 + 231 + spin_lock_irqsave(&tc6393xb->lock, flags); 232 + 233 + __tc6393xb_gpio_set(chip, offset, value); 234 + 235 + doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 236 + doecr |= TC_GPIO_BIT(offset); 237 + iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 238 + 239 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 240 + 241 + return 0; 242 + } 243 + 244 + static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base) 245 + { 246 + tc6393xb->gpio.label = "tc6393xb"; 247 + tc6393xb->gpio.base = gpio_base; 248 + tc6393xb->gpio.ngpio = 16; 249 + tc6393xb->gpio.set = tc6393xb_gpio_set; 250 + tc6393xb->gpio.get = tc6393xb_gpio_get; 251 + tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input; 252 + tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output; 253 + 254 + return gpiochip_add(&tc6393xb->gpio); 255 + } 256 + 257 + /*--------------------------------------------------------------------------*/ 258 + 259 + static void 260 + tc6393xb_irq(unsigned int irq, struct irq_desc *desc) 261 + { 262 + struct tc6393xb *tc6393xb = get_irq_data(irq); 263 + unsigned int isr; 264 + unsigned int i, irq_base; 265 + 266 + irq_base = tc6393xb->irq_base; 267 + 268 + while ((isr = ioread8(tc6393xb->scr + SCR_ISR) & 269 + ~ioread8(tc6393xb->scr + SCR_IMR))) 270 + for (i = 0; i < TC6393XB_NR_IRQS; i++) { 271 + if (isr & (1 << i)) 272 + generic_handle_irq(irq_base + i); 273 + } 274 + } 275 + 276 + static void tc6393xb_irq_ack(unsigned int irq) 277 + { 278 + } 279 + 280 + static void tc6393xb_irq_mask(unsigned int irq) 281 + { 282 + struct tc6393xb *tc6393xb = get_irq_chip_data(irq); 283 + unsigned long flags; 284 + u8 imr; 285 + 286 + spin_lock_irqsave(&tc6393xb->lock, flags); 287 + imr = ioread8(tc6393xb->scr + SCR_IMR); 288 + imr |= 1 << (irq - tc6393xb->irq_base); 289 + iowrite8(imr, tc6393xb->scr + SCR_IMR); 290 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 291 + } 292 + 293 + static void tc6393xb_irq_unmask(unsigned int irq) 294 + { 295 + struct tc6393xb *tc6393xb = get_irq_chip_data(irq); 296 + unsigned long flags; 297 + u8 imr; 298 + 299 + spin_lock_irqsave(&tc6393xb->lock, flags); 300 + imr = ioread8(tc6393xb->scr + SCR_IMR); 301 + imr &= ~(1 << (irq - tc6393xb->irq_base)); 302 + iowrite8(imr, tc6393xb->scr + SCR_IMR); 303 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 304 + } 305 + 306 + static struct irq_chip tc6393xb_chip = { 307 + .name = "tc6393xb", 308 + .ack = tc6393xb_irq_ack, 309 + .mask = tc6393xb_irq_mask, 310 + .unmask = tc6393xb_irq_unmask, 311 + }; 312 + 313 + static void tc6393xb_attach_irq(struct platform_device *dev) 314 + { 315 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 316 + unsigned int irq, irq_base; 317 + 318 + irq_base = tc6393xb->irq_base; 319 + 320 + for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { 321 + set_irq_chip(irq, &tc6393xb_chip); 322 + set_irq_chip_data(irq, tc6393xb); 323 + set_irq_handler(irq, handle_edge_irq); 324 + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 325 + } 326 + 327 + set_irq_type(tc6393xb->irq, IRQT_FALLING); 328 + set_irq_data(tc6393xb->irq, tc6393xb); 329 + set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq); 330 + } 331 + 332 + static void tc6393xb_detach_irq(struct platform_device *dev) 333 + { 334 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 335 + unsigned int irq, irq_base; 336 + 337 + set_irq_chained_handler(tc6393xb->irq, NULL); 338 + set_irq_data(tc6393xb->irq, NULL); 339 + 340 + irq_base = tc6393xb->irq_base; 341 + 342 + for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { 343 + set_irq_flags(irq, 0); 344 + set_irq_chip(irq, NULL); 345 + set_irq_chip_data(irq, NULL); 346 + } 347 + } 348 + 349 + /*--------------------------------------------------------------------------*/ 350 + 351 + static int tc6393xb_hw_init(struct platform_device *dev) 352 + { 353 + struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 354 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 355 + int i; 356 + 357 + iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); 358 + iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); 359 + iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); 360 + iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | 361 + SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | 362 + BIT(15), tc6393xb->scr + SCR_MCR); 363 + iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); 364 + iowrite8(0, tc6393xb->scr + SCR_IRR); 365 + iowrite8(0xbf, tc6393xb->scr + SCR_IMR); 366 + 367 + for (i = 0; i < 3; i++) { 368 + iowrite8(tc6393xb->suspend_state.gpo_dsr[i], 369 + tc6393xb->scr + SCR_GPO_DSR(i)); 370 + iowrite8(tc6393xb->suspend_state.gpo_doecr[i], 371 + tc6393xb->scr + SCR_GPO_DOECR(i)); 372 + iowrite8(tc6393xb->suspend_state.gpi_bcr[i], 373 + tc6393xb->scr + SCR_GPI_BCR(i)); 374 + } 375 + 376 + return 0; 377 + } 378 + 379 + static int __devinit tc6393xb_probe(struct platform_device *dev) 380 + { 381 + struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 382 + struct tc6393xb *tc6393xb; 383 + struct resource *iomem; 384 + struct resource *rscr; 385 + int retval, temp; 386 + int i; 387 + 388 + iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); 389 + if (!iomem) 390 + return -EINVAL; 391 + 392 + tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); 393 + if (!tc6393xb) { 394 + retval = -ENOMEM; 395 + goto err_kzalloc; 396 + } 397 + 398 + spin_lock_init(&tc6393xb->lock); 399 + 400 + platform_set_drvdata(dev, tc6393xb); 401 + tc6393xb->iomem = iomem; 402 + tc6393xb->irq = platform_get_irq(dev, 0); 403 + tc6393xb->irq_base = tcpd->irq_base; 404 + 405 + tc6393xb->clk = clk_get(&dev->dev, "GPIO27_CLK" /* "CK3P6MI" */); 406 + if (IS_ERR(tc6393xb->clk)) { 407 + retval = PTR_ERR(tc6393xb->clk); 408 + goto err_clk_get; 409 + } 410 + 411 + rscr = &tc6393xb->rscr; 412 + rscr->name = "tc6393xb-core"; 413 + rscr->start = iomem->start; 414 + rscr->end = iomem->start + 0xff; 415 + rscr->flags = IORESOURCE_MEM; 416 + 417 + retval = request_resource(iomem, rscr); 418 + if (retval) 419 + goto err_request_scr; 420 + 421 + tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); 422 + if (!tc6393xb->scr) { 423 + retval = -ENOMEM; 424 + goto err_ioremap; 425 + } 426 + 427 + retval = clk_enable(tc6393xb->clk); 428 + if (retval) 429 + goto err_clk_enable; 430 + 431 + retval = tcpd->enable(dev); 432 + if (retval) 433 + goto err_enable; 434 + 435 + tc6393xb->suspend_state.fer = 0; 436 + for (i = 0; i < 3; i++) { 437 + tc6393xb->suspend_state.gpo_dsr[i] = 438 + (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff; 439 + tc6393xb->suspend_state.gpo_doecr[i] = 440 + (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff; 441 + } 442 + /* 443 + * It may be necessary to change this back to 444 + * platform-dependant code 445 + */ 446 + tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | 447 + SCR_CCR_HCLK_48; 448 + 449 + retval = tc6393xb_hw_init(dev); 450 + if (retval) 451 + goto err_hw_init; 452 + 453 + printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", 454 + ioread8(tc6393xb->scr + SCR_REVID), 455 + (unsigned long) iomem->start, tc6393xb->irq); 456 + 457 + tc6393xb->gpio.base = -1; 458 + 459 + if (tcpd->gpio_base >= 0) { 460 + retval = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); 461 + if (retval) 462 + goto err_gpio_add; 463 + } 464 + 465 + if (tc6393xb->irq) 466 + tc6393xb_attach_irq(dev); 467 + 468 + tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; 469 + 470 + retval = mfd_add_devices(dev, 471 + tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), 472 + iomem, tcpd->irq_base); 473 + 474 + return 0; 475 + 476 + if (tc6393xb->irq) 477 + tc6393xb_detach_irq(dev); 478 + 479 + err_gpio_add: 480 + if (tc6393xb->gpio.base != -1) 481 + temp = gpiochip_remove(&tc6393xb->gpio); 482 + err_hw_init: 483 + tcpd->disable(dev); 484 + err_clk_enable: 485 + clk_disable(tc6393xb->clk); 486 + err_enable: 487 + iounmap(tc6393xb->scr); 488 + err_ioremap: 489 + release_resource(&tc6393xb->rscr); 490 + err_request_scr: 491 + clk_put(tc6393xb->clk); 492 + err_clk_get: 493 + kfree(tc6393xb); 494 + err_kzalloc: 495 + return retval; 496 + } 497 + 498 + static int __devexit tc6393xb_remove(struct platform_device *dev) 499 + { 500 + struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 501 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 502 + int ret; 503 + 504 + mfd_remove_devices(dev); 505 + 506 + if (tc6393xb->irq) 507 + tc6393xb_detach_irq(dev); 508 + 509 + if (tc6393xb->gpio.base != -1) { 510 + ret = gpiochip_remove(&tc6393xb->gpio); 511 + if (ret) { 512 + dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret); 513 + return ret; 514 + } 515 + } 516 + 517 + ret = tcpd->disable(dev); 518 + 519 + clk_disable(tc6393xb->clk); 520 + 521 + iounmap(tc6393xb->scr); 522 + 523 + release_resource(&tc6393xb->rscr); 524 + 525 + platform_set_drvdata(dev, NULL); 526 + 527 + clk_put(tc6393xb->clk); 528 + 529 + kfree(tc6393xb); 530 + 531 + return ret; 532 + } 533 + 534 + #ifdef CONFIG_PM 535 + static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) 536 + { 537 + struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 538 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 539 + int i; 540 + 541 + 542 + tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); 543 + tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); 544 + 545 + for (i = 0; i < 3; i++) { 546 + tc6393xb->suspend_state.gpo_dsr[i] = 547 + ioread8(tc6393xb->scr + SCR_GPO_DSR(i)); 548 + tc6393xb->suspend_state.gpo_doecr[i] = 549 + ioread8(tc6393xb->scr + SCR_GPO_DOECR(i)); 550 + tc6393xb->suspend_state.gpi_bcr[i] = 551 + ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); 552 + } 553 + 554 + return tcpd->suspend(dev); 555 + } 556 + 557 + static int tc6393xb_resume(struct platform_device *dev) 558 + { 559 + struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 560 + int ret = tcpd->resume(dev); 561 + 562 + if (ret) 563 + return ret; 564 + 565 + return tc6393xb_hw_init(dev); 566 + } 567 + #else 568 + #define tc6393xb_suspend NULL 569 + #define tc6393xb_resume NULL 570 + #endif 571 + 572 + static struct platform_driver tc6393xb_driver = { 573 + .probe = tc6393xb_probe, 574 + .remove = __devexit_p(tc6393xb_remove), 575 + .suspend = tc6393xb_suspend, 576 + .resume = tc6393xb_resume, 577 + 578 + .driver = { 579 + .name = "tc6393xb", 580 + .owner = THIS_MODULE, 581 + }, 582 + }; 583 + 584 + static int __init tc6393xb_init(void) 585 + { 586 + return platform_driver_register(&tc6393xb_driver); 587 + } 588 + 589 + static void __exit tc6393xb_exit(void) 590 + { 591 + platform_driver_unregister(&tc6393xb_driver); 592 + } 593 + 594 + subsys_initcall(tc6393xb_init); 595 + module_exit(tc6393xb_exit); 596 + 597 + MODULE_LICENSE("GPL"); 598 + MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); 599 + MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); 600 + MODULE_ALIAS("platform:tc6393xb");
+5
include/asm-arm/arch-pxa/hardware.h
··· 208 208 */ 209 209 extern unsigned int get_memclk_frequency_10khz(void); 210 210 211 + /* 212 + * register GPIO as reset generator 213 + */ 214 + extern int init_gpio_reset(int gpio); 215 + 211 216 #endif 212 217 213 218 #if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+1
include/asm-arm/arch-pxa/irqs.h
··· 180 180 #define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1) 181 181 #elif defined(CONFIG_ARCH_LUBBOCK) || \ 182 182 defined(CONFIG_MACH_LOGICPD_PXA270) || \ 183 + defined(CONFIG_MACH_TOSA) || \ 183 184 defined(CONFIG_MACH_MAINSTONE) || \ 184 185 defined(CONFIG_MACH_PCM027) || \ 185 186 defined(CONFIG_MACH_MAGICIAN)
+1 -16
include/asm-arm/arch-pxa/system.h
··· 21 21 } 22 22 23 23 24 - static inline void arch_reset(char mode) 25 - { 26 - if (cpu_is_pxa2xx()) 27 - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; 28 - 29 - if (mode == 's') { 30 - /* Jump into ROM at address 0 */ 31 - cpu_reset(0); 32 - } else { 33 - /* Initialize the watchdog and let it fire */ 34 - OWER = OWER_WME; 35 - OSSR = OSSR_M3; 36 - OSMR3 = OSCR + 368640; /* ... in 100 ms */ 37 - } 38 - } 39 - 24 + void arch_reset(char mode);
+33 -17
include/asm-arm/arch-pxa/tosa.h
··· 25 25 */ 26 26 #define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO 27 27 #define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11 28 - #define TOSA_SCOOP_TC6393_REST_IN SCOOP_GPCR_PA12 28 + #define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1) 29 29 #define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2) 30 30 #define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3) 31 31 #define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4) 32 32 #define TOSA_SCOOP_AUD_PWR_ON SCOOP_GPCR_PA16 33 - #define TOSA_SCOOP_BT_RESET SCOOP_GPCR_PA17 34 - #define TOSA_SCOOP_BT_PWR_EN SCOOP_GPCR_PA18 33 + #define TOSA_GPIO_BT_RESET (TOSA_SCOOP_GPIO_BASE + 6) 34 + #define TOSA_GPIO_BT_PWR_EN (TOSA_SCOOP_GPIO_BASE + 7) 35 35 #define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19 36 36 37 37 /* GPIO Direction 1 : output mode / 0:input mode */ 38 - #define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393_REST_IN | \ 39 - TOSA_SCOOP_AUD_PWR_ON |\ 40 - TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN ) 41 - /* GPIO out put level when init 1: Hi */ 42 - #define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393_REST_IN ) 38 + #define TOSA_SCOOP_IO_DIR (TOSA_SCOOP_PXA_VCORE1 | \ 39 + TOSA_SCOOP_AUD_PWR_ON) 43 40 44 41 /* 45 42 * SCOOP2 jacket GPIOs ··· 46 49 #define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1) 47 50 #define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) 48 51 #define TOSA_GPIO_USB_PULLUP (TOSA_SCOOP_JC_GPIO_BASE + 3) 49 - #define TOSA_SCOOP_JC_TC6393_SUSPEND SCOOP_GPCR_PA15 50 - #define TOSA_SCOOP_JC_TC3693_L3V_ON SCOOP_GPCR_PA16 52 + #define TOSA_GPIO_TC6393XB_SUSPEND (TOSA_SCOOP_JC_GPIO_BASE + 4) 53 + #define TOSA_GPIO_TC6393XB_L3V_ON (TOSA_SCOOP_JC_GPIO_BASE + 5) 51 54 #define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17 52 55 #define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7) 53 56 #define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19 54 57 55 58 /* GPIO Direction 1 : output mode / 0:input mode */ 56 - #define TOSA_SCOOP_JC_IO_DIR ( \ 57 - TOSA_SCOOP_JC_TC6393_SUSPEND | TOSA_SCOOP_JC_TC3693_L3V_ON | \ 58 - TOSA_SCOOP_JC_CARD_LIMIT_SEL ) 59 + #define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL) 60 + 61 + /* 62 + * TC6393XB GPIOs 63 + */ 64 + #define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12) 65 + #define TOSA_TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i)) 66 + #define TOSA_TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE)) 67 + 68 + #define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0) 69 + #define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1) 70 + #define TOSA_GPIO_BL_C20MA (TOSA_TC6393XB_GPIO_BASE + 3) 71 + #define TOSA_GPIO_CARD_VCC_ON (TOSA_TC6393XB_GPIO_BASE + 4) 72 + #define TOSA_GPIO_CHARGE_OFF (TOSA_TC6393XB_GPIO_BASE + 6) 73 + #define TOSA_GPIO_CHARGE_OFF_JC (TOSA_TC6393XB_GPIO_BASE + 7) 74 + #define TOSA_GPIO_BAT0_V_ON (TOSA_TC6393XB_GPIO_BASE + 9) 75 + #define TOSA_GPIO_BAT1_V_ON (TOSA_TC6393XB_GPIO_BASE + 10) 76 + #define TOSA_GPIO_BU_CHRG_ON (TOSA_TC6393XB_GPIO_BASE + 11) 77 + #define TOSA_GPIO_BAT_SW_ON (TOSA_TC6393XB_GPIO_BASE + 12) 78 + #define TOSA_GPIO_BAT0_TH_ON (TOSA_TC6393XB_GPIO_BASE + 14) 79 + #define TOSA_GPIO_BAT1_TH_ON (TOSA_TC6393XB_GPIO_BASE + 15) 59 80 60 81 /* 61 82 * Timing Generator ··· 99 84 #define TOSA_GPIO_JACKET_DETECT (7) 100 85 #define TOSA_GPIO_nSD_DETECT (9) 101 86 #define TOSA_GPIO_nSD_INT (10) 102 - #define TOSA_GPIO_TC6393_CLK (11) 87 + #define TOSA_GPIO_TC6393XB_CLK (11) 103 88 #define TOSA_GPIO_BAT1_CRG (12) 104 89 #define TOSA_GPIO_CF_CD (13) 105 90 #define TOSA_GPIO_BAT0_CRG (14) 106 - #define TOSA_GPIO_TC6393_INT (15) 91 + #define TOSA_GPIO_TC6393XB_INT (15) 107 92 #define TOSA_GPIO_BAT0_LOW (17) 108 - #define TOSA_GPIO_TC6393_RDY (18) 93 + #define TOSA_GPIO_TC6393XB_RDY (18) 109 94 #define TOSA_GPIO_ON_RESET (19) 110 95 #define TOSA_GPIO_EAR_IN (20) 111 96 #define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */ ··· 114 99 #define TOSA_GPIO_TP_INT (32) /* Touch Panel pen down interrupt */ 115 100 #define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */ 116 101 #define TOSA_GPIO_BAT_LOCKED (38) /* Battery locked */ 102 + #define TOSA_GPIO_IRDA_TX (47) 117 103 #define TOSA_GPIO_TG_SPI_SCLK (81) 118 104 #define TOSA_GPIO_TG_SPI_CS (82) 119 105 #define TOSA_GPIO_TG_SPI_MOSI (83) ··· 153 137 #define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG) 154 138 #define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD) 155 139 #define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG) 156 - #define TOSA_IRQ_GPIO_TC6393_INT IRQ_GPIO(TOSA_GPIO_TC6393_INT) 140 + #define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT) 157 141 #define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW) 158 142 #define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN) 159 143 #define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ)
+22
include/asm-arm/arch-pxa/tosa_bt.h
··· 1 + /* 2 + * Tosa bluetooth built-in chip control. 3 + * 4 + * Later it may be shared with some other platforms. 5 + * 6 + * Copyright (c) 2008 Dmitry Baryshkov 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + */ 13 + #ifndef TOSA_BT_H 14 + #define TOSA_BT_H 15 + 16 + struct tosa_bt_data { 17 + int gpio_pwr; 18 + int gpio_reset; 19 + }; 20 + 21 + #endif 22 +
+55
include/linux/mfd/core.h
··· 1 + #ifndef MFD_CORE_H 2 + #define MFD_CORE_H 3 + /* 4 + * drivers/mfd/mfd-core.h 5 + * 6 + * core MFD support 7 + * Copyright (c) 2006 Ian Molton 8 + * Copyright (c) 2007 Dmitry Baryshkov 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + */ 15 + 16 + #include <linux/platform_device.h> 17 + 18 + /* 19 + * This struct describes the MFD part ("cell"). 20 + * After registration the copy of this structure will become the platform data 21 + * of the resulting platform_device 22 + */ 23 + struct mfd_cell { 24 + const char *name; 25 + 26 + int (*enable)(struct platform_device *dev); 27 + int (*disable)(struct platform_device *dev); 28 + int (*suspend)(struct platform_device *dev); 29 + int (*resume)(struct platform_device *dev); 30 + 31 + void *driver_data; /* driver-specific data */ 32 + 33 + /* 34 + * This resources can be specified relatievly to the parent device. 35 + * For accessing device you should use resources from device 36 + */ 37 + int num_resources; 38 + const struct resource *resources; 39 + }; 40 + 41 + static inline struct mfd_cell * 42 + mfd_get_cell(struct platform_device *pdev) 43 + { 44 + return (struct mfd_cell *)pdev->dev.platform_data; 45 + } 46 + 47 + extern int mfd_add_devices( 48 + struct platform_device *parent, 49 + const struct mfd_cell *cells, int n_devs, 50 + struct resource *mem_base, 51 + int irq_base); 52 + 53 + extern void mfd_remove_devices(struct platform_device *parent); 54 + 55 + #endif
+49
include/linux/mfd/tc6393xb.h
··· 1 + /* 2 + * Toshiba TC6393XB SoC support 3 + * 4 + * Copyright(c) 2005-2006 Chris Humbert 5 + * Copyright(c) 2005 Dirk Opfer 6 + * Copyright(c) 2005 Ian Molton <spyro@f2s.com> 7 + * Copyright(c) 2007 Dmitry Baryshkov 8 + * 9 + * Based on code written by Sharp/Lineo for 2.4 kernels 10 + * Based on locomo.c 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License version 2 as 14 + * published by the Free Software Foundation. 15 + */ 16 + 17 + #ifndef TC6393XB_H 18 + #define TC6393XB_H 19 + 20 + /* Also one should provide the CK3P6MI clock */ 21 + struct tc6393xb_platform_data { 22 + u16 scr_pll2cr; /* PLL2 Control */ 23 + u16 scr_gper; /* GP Enable */ 24 + u32 scr_gpo_doecr; /* GPO Data OE Control */ 25 + u32 scr_gpo_dsr; /* GPO Data Set */ 26 + 27 + int (*enable)(struct platform_device *dev); 28 + int (*disable)(struct platform_device *dev); 29 + int (*suspend)(struct platform_device *dev); 30 + int (*resume)(struct platform_device *dev); 31 + 32 + int irq_base; /* a base for cascaded irq */ 33 + int gpio_base; 34 + 35 + struct tmio_nand_data *nand_data; 36 + }; 37 + 38 + /* 39 + * Relative to irq_base 40 + */ 41 + #define IRQ_TC6393_NAND 0 42 + #define IRQ_TC6393_MMC 1 43 + #define IRQ_TC6393_OHCI 2 44 + #define IRQ_TC6393_SERIAL 3 45 + #define IRQ_TC6393_FB 4 46 + 47 + #define TC6393XB_NR_IRQS 8 48 + 49 + #endif
+17
include/linux/mfd/tmio.h
··· 1 + #ifndef MFD_TMIO_H 2 + #define MFD_TMIO_H 3 + 4 + /* 5 + * data for the NAND controller 6 + */ 7 + struct tmio_nand_data { 8 + struct nand_bbt_descr *badblock_pattern; 9 + struct mtd_partition *partition; 10 + unsigned int num_partitions; 11 + }; 12 + 13 + #define TMIO_NAND_CONFIG "tmio-nand-config" 14 + #define TMIO_NAND_CONTROL "tmio-nand-control" 15 + #define TMIO_NAND_IRQ "tmio-nand" 16 + 17 + #endif
+1
sound/soc/pxa/Kconfig
··· 48 48 config SND_PXA2XX_SOC_TOSA 49 49 tristate "SoC AC97 Audio support for Tosa" 50 50 depends on SND_PXA2XX_SOC && MACH_TOSA 51 + depends on MFD_TC6393XB 51 52 select SND_PXA2XX_SOC_AC97 52 53 select SND_SOC_WM9712 53 54 help
+20 -9
sound/soc/pxa/tosa.c
··· 24 24 #include <linux/module.h> 25 25 #include <linux/moduleparam.h> 26 26 #include <linux/device.h> 27 + #include <linux/gpio.h> 27 28 28 29 #include <sound/core.h> 29 30 #include <sound/pcm.h> ··· 32 31 #include <sound/soc-dapm.h> 33 32 34 33 #include <asm/mach-types.h> 35 - #include <asm/hardware/tmio.h> 34 + #include <asm/arch/tosa.h> 36 35 #include <asm/arch/pxa-regs.h> 37 36 #include <asm/arch/hardware.h> 38 37 #include <asm/arch/audio.h> ··· 139 138 static int tosa_hp_event(struct snd_soc_dapm_widget *w, 140 139 struct snd_kcontrol *k, int event) 141 140 { 142 - if (SND_SOC_DAPM_EVENT_ON(event)) 143 - set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); 144 - else 145 - reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); 141 + gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 :0); 146 142 return 0; 147 143 } 148 144 ··· 259 261 if (!machine_is_tosa()) 260 262 return -ENODEV; 261 263 264 + ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack"); 265 + if (ret) 266 + return ret; 267 + gpio_direction_output(TOSA_GPIO_L_MUTE, 0); 268 + 262 269 tosa_snd_device = platform_device_alloc("soc-audio", -1); 263 - if (!tosa_snd_device) 264 - return -ENOMEM; 270 + if (!tosa_snd_device) { 271 + ret = -ENOMEM; 272 + goto err_alloc; 273 + } 265 274 266 275 platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata); 267 276 tosa_snd_devdata.dev = &tosa_snd_device->dev; 268 277 ret = platform_device_add(tosa_snd_device); 269 278 270 - if (ret) 271 - platform_device_put(tosa_snd_device); 279 + if (!ret) 280 + return 0; 281 + 282 + platform_device_put(tosa_snd_device); 283 + 284 + err_alloc: 285 + gpio_free(TOSA_GPIO_L_MUTE); 272 286 273 287 return ret; 274 288 } ··· 288 278 static void __exit tosa_exit(void) 289 279 { 290 280 platform_device_unregister(tosa_snd_device); 281 + gpio_free(TOSA_GPIO_L_MUTE); 291 282 } 292 283 293 284 module_init(tosa_init);