poodle.c (10817B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/arch/arm/mach-pxa/poodle.c 4 * 5 * Support for the SHARP Poodle Board. 6 * 7 * Based on: 8 * linux/arch/arm/mach-pxa/lubbock.c Author: Nicolas Pitre 9 * 10 * Change Log 11 * 12-Dec-2002 Sharp Corporation for Poodle 12 * John Lenz <lenz@cs.wisc.edu> updates to 2.6 13 */ 14#include <linux/kernel.h> 15#include <linux/init.h> 16#include <linux/export.h> 17#include <linux/platform_device.h> 18#include <linux/fb.h> 19#include <linux/pm.h> 20#include <linux/delay.h> 21#include <linux/mtd/physmap.h> 22#include <linux/gpio.h> 23#include <linux/gpio/machine.h> 24#include <linux/i2c.h> 25#include <linux/platform_data/i2c-pxa.h> 26#include <linux/regulator/machine.h> 27#include <linux/spi/spi.h> 28#include <linux/spi/ads7846.h> 29#include <linux/spi/pxa2xx_spi.h> 30#include <linux/mtd/sharpsl.h> 31#include <linux/memblock.h> 32 33#include <asm/mach-types.h> 34#include <asm/irq.h> 35#include <asm/setup.h> 36 37#include <asm/mach/arch.h> 38#include <asm/mach/map.h> 39#include <asm/mach/irq.h> 40 41#include "pxa25x.h" 42#include "udc.h" 43#include "poodle.h" 44 45#include <linux/platform_data/mmc-pxamci.h> 46#include <linux/platform_data/irda-pxaficp.h> 47#include <linux/platform_data/video-pxafb.h> 48#include <linux/platform_data/asoc-poodle.h> 49 50#include <asm/hardware/scoop.h> 51#include <asm/hardware/locomo.h> 52#include <asm/mach/sharpsl_param.h> 53 54#include "generic.h" 55#include "devices.h" 56 57static unsigned long poodle_pin_config[] __initdata = { 58 /* I/O */ 59 GPIO79_nCS_3, 60 GPIO80_nCS_4, 61 GPIO18_RDY, 62 63 /* Clock */ 64 GPIO12_32KHz, 65 66 /* SSP1 */ 67 GPIO23_SSP1_SCLK, 68 GPIO25_SSP1_TXD, 69 GPIO26_SSP1_RXD, 70 GPIO24_GPIO, /* POODLE_GPIO_TP_CS - SFRM as chip select */ 71 72 /* I2S */ 73 GPIO28_I2S_BITCLK_OUT, 74 GPIO29_I2S_SDATA_IN, 75 GPIO30_I2S_SDATA_OUT, 76 GPIO31_I2S_SYNC, 77 GPIO32_I2S_SYSCLK, 78 79 /* Infra-Red */ 80 GPIO47_FICP_TXD, 81 GPIO46_FICP_RXD, 82 83 /* FFUART */ 84 GPIO40_FFUART_DTR, 85 GPIO41_FFUART_RTS, 86 GPIO39_FFUART_TXD, 87 GPIO37_FFUART_DSR, 88 GPIO34_FFUART_RXD, 89 GPIO35_FFUART_CTS, 90 91 /* LCD */ 92 GPIOxx_LCD_TFT_16BPP, 93 94 /* PC Card */ 95 GPIO48_nPOE, 96 GPIO49_nPWE, 97 GPIO50_nPIOR, 98 GPIO51_nPIOW, 99 GPIO52_nPCE_1, 100 GPIO53_nPCE_2, 101 GPIO54_nPSKTSEL, 102 GPIO55_nPREG, 103 GPIO56_nPWAIT, 104 GPIO57_nIOIS16, 105 106 /* MMC */ 107 GPIO6_MMC_CLK, 108 GPIO8_MMC_CS0, 109 110 /* GPIO */ 111 GPIO9_GPIO, /* POODLE_GPIO_nSD_DETECT */ 112 GPIO7_GPIO, /* POODLE_GPIO_nSD_WP */ 113 GPIO3_GPIO, /* POODLE_GPIO_SD_PWR */ 114 GPIO33_GPIO, /* POODLE_GPIO_SD_PWR1 */ 115 116 GPIO20_GPIO, /* POODLE_GPIO_USB_PULLUP */ 117 GPIO22_GPIO, /* POODLE_GPIO_IR_ON */ 118}; 119 120static struct resource poodle_scoop_resources[] = { 121 [0] = { 122 .start = 0x10800000, 123 .end = 0x10800fff, 124 .flags = IORESOURCE_MEM, 125 }, 126}; 127 128static struct scoop_config poodle_scoop_setup = { 129 .io_dir = POODLE_SCOOP_IO_DIR, 130 .io_out = POODLE_SCOOP_IO_OUT, 131 .gpio_base = POODLE_SCOOP_GPIO_BASE, 132}; 133 134struct platform_device poodle_scoop_device = { 135 .name = "sharp-scoop", 136 .id = -1, 137 .dev = { 138 .platform_data = &poodle_scoop_setup, 139 }, 140 .num_resources = ARRAY_SIZE(poodle_scoop_resources), 141 .resource = poodle_scoop_resources, 142}; 143 144static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { 145{ 146 .dev = &poodle_scoop_device.dev, 147 .irq = POODLE_IRQ_GPIO_CF_IRQ, 148 .cd_irq = POODLE_IRQ_GPIO_CF_CD, 149 .cd_irq_str = "PCMCIA0 CD", 150}, 151}; 152 153static struct scoop_pcmcia_config poodle_pcmcia_config = { 154 .devs = &poodle_pcmcia_scoop[0], 155 .num_devs = 1, 156}; 157 158EXPORT_SYMBOL(poodle_scoop_device); 159 160/* LoCoMo device */ 161static struct resource locomo_resources[] = { 162 [0] = { 163 .start = 0x10000000, 164 .end = 0x10001fff, 165 .flags = IORESOURCE_MEM, 166 }, 167 [1] = { 168 .start = PXA_GPIO_TO_IRQ(10), 169 .end = PXA_GPIO_TO_IRQ(10), 170 .flags = IORESOURCE_IRQ, 171 }, 172}; 173 174static struct locomo_platform_data locomo_info = { 175 .irq_base = IRQ_BOARD_START, 176}; 177 178static struct platform_device poodle_locomo_device = { 179 .name = "locomo", 180 .id = 0, 181 .num_resources = ARRAY_SIZE(locomo_resources), 182 .resource = locomo_resources, 183 .dev = { 184 .platform_data = &locomo_info, 185 }, 186}; 187 188static struct poodle_audio_platform_data poodle_audio_pdata = { 189 .locomo_dev = &poodle_locomo_device.dev, 190 191 .gpio_amp_on = POODLE_LOCOMO_GPIO_AMP_ON, 192 .gpio_mute_l = POODLE_LOCOMO_GPIO_MUTE_L, 193 .gpio_mute_r = POODLE_LOCOMO_GPIO_MUTE_R, 194 .gpio_232vcc_on = POODLE_LOCOMO_GPIO_232VCC_ON, 195 .gpio_jk_b = POODLE_LOCOMO_GPIO_JK_B, 196}; 197 198static struct platform_device poodle_audio_device = { 199 .name = "poodle-audio", 200 .id = -1, 201 .dev.platform_data = &poodle_audio_pdata, 202}; 203 204#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) 205static struct pxa2xx_spi_controller poodle_spi_info = { 206 .num_chipselect = 1, 207}; 208 209static struct gpiod_lookup_table poodle_spi_gpio_table = { 210 .dev_id = "pxa2xx-spi.1", 211 .table = { 212 GPIO_LOOKUP_IDX("gpio-pxa", POODLE_GPIO_TP_CS, "cs", 0, GPIO_ACTIVE_LOW), 213 { }, 214 }, 215}; 216 217static struct ads7846_platform_data poodle_ads7846_info = { 218 .model = 7846, 219 .vref_delay_usecs = 100, 220 .x_plate_ohms = 419, 221 .y_plate_ohms = 486, 222 .gpio_pendown = POODLE_GPIO_TP_INT, 223}; 224 225static struct spi_board_info poodle_spi_devices[] = { 226 { 227 .modalias = "ads7846", 228 .max_speed_hz = 10000, 229 .bus_num = 1, 230 .platform_data = &poodle_ads7846_info, 231 .irq = PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT), 232 }, 233}; 234 235static void __init poodle_init_spi(void) 236{ 237 gpiod_add_lookup_table(&poodle_spi_gpio_table); 238 pxa2xx_set_spi_info(1, &poodle_spi_info); 239 spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices)); 240} 241#else 242static inline void poodle_init_spi(void) {} 243#endif 244 245/* 246 * MMC/SD Device 247 * 248 * The card detect interrupt isn't debounced so we delay it by 250ms 249 * to give the card a chance to fully insert/eject. 250 */ 251static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data) 252{ 253 int err; 254 255 err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR"); 256 if (err) 257 goto err_free_2; 258 259 err = gpio_request(POODLE_GPIO_SD_PWR1, "SD_PWR1"); 260 if (err) 261 goto err_free_3; 262 263 gpio_direction_output(POODLE_GPIO_SD_PWR, 0); 264 gpio_direction_output(POODLE_GPIO_SD_PWR1, 0); 265 266 return 0; 267 268err_free_3: 269 gpio_free(POODLE_GPIO_SD_PWR); 270err_free_2: 271 return err; 272} 273 274static int poodle_mci_setpower(struct device *dev, unsigned int vdd) 275{ 276 struct pxamci_platform_data* p_d = dev->platform_data; 277 278 if ((1 << vdd) & p_d->ocr_mask) { 279 gpio_set_value(POODLE_GPIO_SD_PWR, 1); 280 mdelay(2); 281 gpio_set_value(POODLE_GPIO_SD_PWR1, 1); 282 } else { 283 gpio_set_value(POODLE_GPIO_SD_PWR1, 0); 284 gpio_set_value(POODLE_GPIO_SD_PWR, 0); 285 } 286 287 return 0; 288} 289 290static void poodle_mci_exit(struct device *dev, void *data) 291{ 292 gpio_free(POODLE_GPIO_SD_PWR1); 293 gpio_free(POODLE_GPIO_SD_PWR); 294} 295 296static struct pxamci_platform_data poodle_mci_platform_data = { 297 .detect_delay_ms = 250, 298 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 299 .init = poodle_mci_init, 300 .setpower = poodle_mci_setpower, 301 .exit = poodle_mci_exit, 302}; 303 304static struct gpiod_lookup_table poodle_mci_gpio_table = { 305 .dev_id = "pxa2xx-mci.0", 306 .table = { 307 GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_DETECT, 308 "cd", GPIO_ACTIVE_LOW), 309 GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_WP, 310 "wp", GPIO_ACTIVE_LOW), 311 { }, 312 }, 313}; 314 315/* 316 * Irda 317 */ 318static struct pxaficp_platform_data poodle_ficp_platform_data = { 319 .gpio_pwdown = POODLE_GPIO_IR_ON, 320 .transceiver_cap = IR_SIRMODE | IR_OFF, 321}; 322 323 324/* 325 * USB Device Controller 326 */ 327static struct pxa2xx_udc_mach_info udc_info __initdata = { 328 /* no connect GPIO; poodle can't tell connection status */ 329 .gpio_pullup = POODLE_GPIO_USB_PULLUP, 330}; 331 332 333/* PXAFB device */ 334static struct pxafb_mode_info poodle_fb_mode = { 335 .pixclock = 144700, 336 .xres = 320, 337 .yres = 240, 338 .bpp = 16, 339 .hsync_len = 7, 340 .left_margin = 11, 341 .right_margin = 30, 342 .vsync_len = 2, 343 .upper_margin = 2, 344 .lower_margin = 0, 345 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 346}; 347 348static struct pxafb_mach_info poodle_fb_info = { 349 .modes = &poodle_fb_mode, 350 .num_modes = 1, 351 .lcd_conn = LCD_COLOR_TFT_16BPP, 352}; 353 354static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 355 356static struct nand_bbt_descr sharpsl_bbt = { 357 .options = 0, 358 .offs = 4, 359 .len = 2, 360 .pattern = scan_ff_pattern 361}; 362 363static const char * const probes[] = { 364 "cmdlinepart", 365 "ofpart", 366 "sharpslpart", 367 NULL, 368}; 369 370static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = { 371 .badblock_pattern = &sharpsl_bbt, 372 .part_parsers = probes, 373}; 374 375static struct resource sharpsl_nand_resources[] = { 376 { 377 .start = 0x0C000000, 378 .end = 0x0C000FFF, 379 .flags = IORESOURCE_MEM, 380 }, 381}; 382 383static struct platform_device sharpsl_nand_device = { 384 .name = "sharpsl-nand", 385 .id = -1, 386 .resource = sharpsl_nand_resources, 387 .num_resources = ARRAY_SIZE(sharpsl_nand_resources), 388 .dev.platform_data = &sharpsl_nand_platform_data, 389}; 390 391static struct mtd_partition sharpsl_rom_parts[] = { 392 { 393 .name ="Boot PROM Filesystem", 394 .offset = 0x00120000, 395 .size = MTDPART_SIZ_FULL, 396 }, 397}; 398 399static struct physmap_flash_data sharpsl_rom_data = { 400 .width = 2, 401 .nr_parts = ARRAY_SIZE(sharpsl_rom_parts), 402 .parts = sharpsl_rom_parts, 403}; 404 405static struct resource sharpsl_rom_resources[] = { 406 { 407 .start = 0x00000000, 408 .end = 0x007fffff, 409 .flags = IORESOURCE_MEM, 410 }, 411}; 412 413static struct platform_device sharpsl_rom_device = { 414 .name = "physmap-flash", 415 .id = -1, 416 .resource = sharpsl_rom_resources, 417 .num_resources = ARRAY_SIZE(sharpsl_rom_resources), 418 .dev.platform_data = &sharpsl_rom_data, 419}; 420 421static struct platform_device *devices[] __initdata = { 422 &poodle_locomo_device, 423 &poodle_scoop_device, 424 &poodle_audio_device, 425 &sharpsl_nand_device, 426 &sharpsl_rom_device, 427}; 428 429static struct i2c_board_info __initdata poodle_i2c_devices[] = { 430 { I2C_BOARD_INFO("wm8731", 0x1b) }, 431}; 432 433static void poodle_poweroff(void) 434{ 435 pxa_restart(REBOOT_HARD, NULL); 436} 437 438static void __init poodle_init(void) 439{ 440 int ret = 0; 441 442 pm_power_off = poodle_poweroff; 443 444 PCFR |= PCFR_OPDE; 445 446 pxa2xx_mfp_config(ARRAY_AND_SIZE(poodle_pin_config)); 447 448 pxa_set_ffuart_info(NULL); 449 pxa_set_btuart_info(NULL); 450 pxa_set_stuart_info(NULL); 451 452 platform_scoop_config = &poodle_pcmcia_config; 453 454 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 455 if (ret) 456 pr_warn("poodle: Unable to register LoCoMo device\n"); 457 458 pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); 459 pxa_set_udc_info(&udc_info); 460 gpiod_add_lookup_table(&poodle_mci_gpio_table); 461 pxa_set_mci_info(&poodle_mci_platform_data); 462 pxa_set_ficp_info(&poodle_ficp_platform_data); 463 pxa_set_i2c_info(NULL); 464 i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices)); 465 poodle_init_spi(); 466 regulator_has_full_constraints(); 467} 468 469static void __init fixup_poodle(struct tag *tags, char **cmdline) 470{ 471 sharpsl_save_param(); 472 memblock_add(0xa0000000, SZ_32M); 473} 474 475MACHINE_START(POODLE, "SHARP Poodle") 476 .fixup = fixup_poodle, 477 .map_io = pxa25x_map_io, 478 .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */ 479 .init_irq = pxa25x_init_irq, 480 .handle_irq = pxa25x_handle_irq, 481 .init_time = pxa_timer_init, 482 .init_machine = poodle_init, 483 .restart = pxa_restart, 484MACHINE_END