linux/arch/arm/mach-pxa/pcm990-baseboard.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  arch/arm/mach-pxa/pcm990-baseboard.c
   4 *  Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
   5 *
   6 *  Refer
   7 *   http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
   8 *  for additional hardware info
   9 *
  10 *  Author:     Juergen Kilb
  11 *  Created:    April 05, 2005
  12 *  Copyright:  Phytec Messtechnik GmbH
  13 *  e-Mail:     armlinux@phytec.de
  14 *
  15 *  based on Intel Mainstone Board
  16 *
  17 *  Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
  18 */
  19#include <linux/gpio.h>
  20#include <linux/irq.h>
  21#include <linux/platform_device.h>
  22#include <linux/i2c.h>
  23#include <linux/platform_data/i2c-pxa.h>
  24#include <linux/pwm.h>
  25#include <linux/pwm_backlight.h>
  26
  27#include <asm/mach/map.h>
  28#include "pxa27x.h"
  29#include <mach/audio.h>
  30#include <linux/platform_data/mmc-pxamci.h>
  31#include <linux/platform_data/usb-ohci-pxa27x.h>
  32#include "pcm990_baseboard.h"
  33#include <linux/platform_data/video-pxafb.h>
  34
  35#include "devices.h"
  36#include "generic.h"
  37
  38static unsigned long pcm990_pin_config[] __initdata = {
  39        /* MMC */
  40        GPIO32_MMC_CLK,
  41        GPIO112_MMC_CMD,
  42        GPIO92_MMC_DAT_0,
  43        GPIO109_MMC_DAT_1,
  44        GPIO110_MMC_DAT_2,
  45        GPIO111_MMC_DAT_3,
  46        /* USB */
  47        GPIO88_USBH1_PWR,
  48        GPIO89_USBH1_PEN,
  49        /* PWM0 */
  50        GPIO16_PWM0_OUT,
  51
  52        /* I2C */
  53        GPIO117_I2C_SCL,
  54        GPIO118_I2C_SDA,
  55
  56        /* AC97 */
  57        GPIO28_AC97_BITCLK,
  58        GPIO29_AC97_SDATA_IN_0,
  59        GPIO30_AC97_SDATA_OUT,
  60        GPIO31_AC97_SYNC,
  61};
  62
  63static void __iomem *pcm990_cpld_base;
  64
  65static u8 pcm990_cpld_readb(unsigned int reg)
  66{
  67        return readb(pcm990_cpld_base + reg);
  68}
  69
  70static void pcm990_cpld_writeb(u8 value, unsigned int reg)
  71{
  72        writeb(value, pcm990_cpld_base + reg);
  73}
  74
  75/*
  76 * pcm990_lcd_power - control power supply to the LCD
  77 * @on: 0 = switch off, 1 = switch on
  78 *
  79 * Called by the pxafb driver
  80 */
  81#ifndef CONFIG_PCM990_DISPLAY_NONE
  82static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var)
  83{
  84        if (on) {
  85                /* enable LCD-Latches
  86                 * power on LCD
  87                 */
  88                pcm990_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON,
  89                                PCM990_CTRL_REG3);
  90        } else {
  91                /* disable LCD-Latches
  92                 * power off LCD
  93                 */
  94                pcm990_cpld_writeb(0, PCM990_CTRL_REG3);
  95        }
  96}
  97#endif
  98
  99#if defined(CONFIG_PCM990_DISPLAY_SHARP)
 100static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = {
 101        .pixclock               = 28000,
 102        .xres                   = 640,
 103        .yres                   = 480,
 104        .bpp                    = 16,
 105        .hsync_len              = 20,
 106        .left_margin            = 103,
 107        .right_margin           = 47,
 108        .vsync_len              = 6,
 109        .upper_margin           = 28,
 110        .lower_margin           = 5,
 111        .sync                   = 0,
 112        .cmap_greyscale         = 0,
 113};
 114
 115static struct pxafb_mach_info pcm990_fbinfo __initdata = {
 116        .modes                  = &fb_info_sharp_lq084v1dg21,
 117        .num_modes              = 1,
 118        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 119        .pxafb_lcd_power        = pcm990_lcd_power,
 120};
 121#elif defined(CONFIG_PCM990_DISPLAY_NEC)
 122struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = {
 123        .pixclock               = 39720,
 124        .xres                   = 640,
 125        .yres                   = 480,
 126        .bpp                    = 16,
 127        .hsync_len              = 32,
 128        .left_margin            = 16,
 129        .right_margin           = 48,
 130        .vsync_len              = 2,
 131        .upper_margin           = 12,
 132        .lower_margin           = 17,
 133        .sync                   = 0,
 134        .cmap_greyscale         = 0,
 135};
 136
 137static struct pxafb_mach_info pcm990_fbinfo __initdata = {
 138        .modes                  = &fb_info_nec_nl6448bc20_18d,
 139        .num_modes              = 1,
 140        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 141        .pxafb_lcd_power        = pcm990_lcd_power,
 142};
 143#endif
 144
 145static struct pwm_lookup pcm990_pwm_lookup[] = {
 146        PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
 147                   PWM_POLARITY_NORMAL),
 148};
 149
 150static struct platform_pwm_backlight_data pcm990_backlight_data = {
 151        .max_brightness = 1023,
 152        .dft_brightness = 1023,
 153};
 154
 155static struct platform_device pcm990_backlight_device = {
 156        .name           = "pwm-backlight",
 157        .dev            = {
 158                .parent = &pxa27x_device_pwm0.dev,
 159                .platform_data = &pcm990_backlight_data,
 160        },
 161};
 162
 163/*
 164 * The PCM-990 development baseboard uses PCM-027's hardware in the
 165 * following way:
 166 *
 167 * - LCD support is in use
 168 *  - GPIO16 is output for back light on/off with PWM
 169 *  - GPIO58 ... GPIO73 are outputs for display data
 170 *  - GPIO74 is output output for LCDFCLK
 171 *  - GPIO75 is output for LCDLCLK
 172 *  - GPIO76 is output for LCDPCLK
 173 *  - GPIO77 is output for LCDBIAS
 174 * - MMC support is in use
 175 *  - GPIO32 is output for MMCCLK
 176 *  - GPIO92 is MMDAT0
 177 *  - GPIO109 is MMDAT1
 178 *  - GPIO110 is MMCS0
 179 *  - GPIO111 is MMCS1
 180 *  - GPIO112 is MMCMD
 181 * - IDE/CF card is in use
 182 *  - GPIO48 is output /POE
 183 *  - GPIO49 is output /PWE
 184 *  - GPIO50 is output /PIOR
 185 *  - GPIO51 is output /PIOW
 186 *  - GPIO54 is output /PCE2
 187 *  - GPIO55 is output /PREG
 188 *  - GPIO56 is input /PWAIT
 189 *  - GPIO57 is output /PIOS16
 190 *  - GPIO79 is output PSKTSEL
 191 *  - GPIO85 is output /PCE1
 192 * - FFUART is in use
 193 *  - GPIO34 is input FFRXD
 194 *  - GPIO35 is input FFCTS
 195 *  - GPIO36 is input FFDCD
 196 *  - GPIO37 is input FFDSR
 197 *  - GPIO38 is input FFRI
 198 *  - GPIO39 is output FFTXD
 199 *  - GPIO40 is output FFDTR
 200 *  - GPIO41 is output FFRTS
 201 * - BTUART is in use
 202 *  - GPIO42 is input BTRXD
 203 *  - GPIO43 is output BTTXD
 204 *  - GPIO44 is input BTCTS
 205 *  - GPIO45 is output BTRTS
 206 * - IRUART is in use
 207 *  - GPIO46 is input STDRXD
 208 *  - GPIO47 is output STDTXD
 209 * - AC97 is in use*)
 210 *  - GPIO28 is input AC97CLK
 211 *  - GPIO29 is input AC97DatIn
 212 *  - GPIO30 is output AC97DatO
 213 *  - GPIO31 is output AC97SYNC
 214 *  - GPIO113 is output AC97_RESET
 215 * - SSP is in use
 216 *  - GPIO23 is output SSPSCLK
 217 *  - GPIO24 is output chip select to Max7301
 218 *  - GPIO25 is output SSPTXD
 219 *  - GPIO26 is input SSPRXD
 220 *  - GPIO27 is input for Max7301 IRQ
 221 *  - GPIO53 is input SSPSYSCLK
 222 * - SSP3 is in use
 223 *  - GPIO81 is output SSPTXD3
 224 *  - GPIO82 is input SSPRXD3
 225 *  - GPIO83 is output SSPSFRM
 226 *  - GPIO84 is output SSPCLK3
 227 *
 228 * Otherwise claimed GPIOs:
 229 * GPIO1 -> IRQ from user switch
 230 * GPIO9 -> IRQ from power management
 231 * GPIO10 -> IRQ from WML9712 AC97 controller
 232 * GPIO11 -> IRQ from IDE controller
 233 * GPIO12 -> IRQ from CF controller
 234 * GPIO13 -> IRQ from CF controller
 235 * GPIO14 -> GPIO free
 236 * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
 237 * GPIO19 -> GPIO free
 238 * GPIO20 -> /SDCS2
 239 * GPIO21 -> /CS3 PC card socket select
 240 * GPIO33 -> /CS5  network controller select
 241 * GPIO78 -> /CS2  (16 bit wide data path)
 242 * GPIO80 -> /CS4  (16 bit wide data path)
 243 * GPIO86 -> GPIO free
 244 * GPIO87 -> GPIO free
 245 * GPIO90 -> LED0 on CPU module
 246 * GPIO91 -> LED1 on CPI module
 247 * GPIO117 -> SCL
 248 * GPIO118 -> SDA
 249 */
 250
 251static unsigned long pcm990_irq_enabled;
 252
 253static void pcm990_mask_ack_irq(struct irq_data *d)
 254{
 255        int pcm990_irq = (d->irq - PCM027_IRQ(0));
 256
 257        pcm990_irq_enabled &= ~(1 << pcm990_irq);
 258
 259        pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
 260}
 261
 262static void pcm990_unmask_irq(struct irq_data *d)
 263{
 264        int pcm990_irq = (d->irq - PCM027_IRQ(0));
 265        u8 val;
 266
 267        /* the irq can be acknowledged only if deasserted, so it's done here */
 268
 269        pcm990_irq_enabled |= (1 << pcm990_irq);
 270
 271        val = pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
 272        val |= 1 << pcm990_irq;
 273        pcm990_cpld_writeb(val, PCM990_CTRL_INTSETCLR);
 274
 275        pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
 276}
 277
 278static struct irq_chip pcm990_irq_chip = {
 279        .irq_mask_ack   = pcm990_mask_ack_irq,
 280        .irq_unmask     = pcm990_unmask_irq,
 281};
 282
 283static void pcm990_irq_handler(struct irq_desc *desc)
 284{
 285        unsigned int irq;
 286        unsigned long pending;
 287
 288        pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
 289        pending &= pcm990_irq_enabled;
 290
 291        do {
 292                /* clear our parent IRQ */
 293                desc->irq_data.chip->irq_ack(&desc->irq_data);
 294                if (likely(pending)) {
 295                        irq = PCM027_IRQ(0) + __ffs(pending);
 296                        generic_handle_irq(irq);
 297                }
 298                pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
 299                pending &= pcm990_irq_enabled;
 300        } while (pending);
 301}
 302
 303static void __init pcm990_init_irq(void)
 304{
 305        int irq;
 306
 307        /* setup extra PCM990 irqs */
 308        for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
 309                irq_set_chip_and_handler(irq, &pcm990_irq_chip,
 310                                         handle_level_irq);
 311                irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
 312        }
 313
 314        /* disable all Interrupts */
 315        pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA);
 316        pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR);
 317
 318        irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
 319        irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
 320}
 321
 322static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
 323                        void *data)
 324{
 325        int err;
 326
 327        err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, 0,
 328                             "MMC card detect", data);
 329        if (err)
 330                printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
 331                                "card detect IRQ\n");
 332
 333        return err;
 334}
 335
 336static int pcm990_mci_setpower(struct device *dev, unsigned int vdd)
 337{
 338        struct pxamci_platform_data *p_d = dev->platform_data;
 339        u8 val;
 340
 341        val = pcm990_cpld_readb(PCM990_CTRL_REG5);
 342
 343        if ((1 << vdd) & p_d->ocr_mask)
 344                val |= PCM990_CTRL_MMC2PWR;
 345        else
 346                val &= ~PCM990_CTRL_MMC2PWR;
 347
 348        pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
 349        return 0;
 350}
 351
 352static void pcm990_mci_exit(struct device *dev, void *data)
 353{
 354        free_irq(PCM027_MMCDET_IRQ, data);
 355}
 356
 357#define MSECS_PER_JIFFY (1000/HZ)
 358
 359static struct pxamci_platform_data pcm990_mci_platform_data = {
 360        .detect_delay_ms        = 250,
 361        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
 362        .init                   = pcm990_mci_init,
 363        .setpower               = pcm990_mci_setpower,
 364        .exit                   = pcm990_mci_exit,
 365};
 366
 367static struct pxaohci_platform_data pcm990_ohci_platform_data = {
 368        .port_mode      = PMM_PERPORT_MODE,
 369        .flags          = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 370        .power_on_delay = 10,
 371};
 372
 373/*
 374 * system init for baseboard usage. Will be called by pcm027 init.
 375 *
 376 * Add platform devices present on this baseboard and init
 377 * them from CPU side as far as required to use them later on
 378 */
 379void __init pcm990_baseboard_init(void)
 380{
 381        pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));
 382
 383        pcm990_cpld_base = ioremap(PCM990_CTRL_PHYS, PCM990_CTRL_SIZE);
 384        if (!pcm990_cpld_base) {
 385                pr_err("pcm990: failed to ioremap cpld\n");
 386                return;
 387        }
 388
 389        /* register CPLD's IRQ controller */
 390        pcm990_init_irq();
 391
 392#ifndef CONFIG_PCM990_DISPLAY_NONE
 393        pxa_set_fb_info(NULL, &pcm990_fbinfo);
 394#endif
 395        pwm_add_table(pcm990_pwm_lookup, ARRAY_SIZE(pcm990_pwm_lookup));
 396        platform_device_register(&pcm990_backlight_device);
 397
 398        /* MMC */
 399        pxa_set_mci_info(&pcm990_mci_platform_data);
 400
 401        /* USB host */
 402        pxa_set_ohci_info(&pcm990_ohci_platform_data);
 403
 404        pxa_set_i2c_info(NULL);
 405        pxa_set_ac97_info(NULL);
 406
 407        printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
 408}
 409