Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  arch/arm/mach-pxa/pcm990-baseboard.c
0004  *  Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
0005  *
0006  *  Refer
0007  *   http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
0008  *  for additional hardware info
0009  *
0010  *  Author: Juergen Kilb
0011  *  Created:    April 05, 2005
0012  *  Copyright:  Phytec Messtechnik GmbH
0013  *  e-Mail: armlinux@phytec.de
0014  *
0015  *  based on Intel Mainstone Board
0016  *
0017  *  Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
0018  */
0019 #include <linux/gpio.h>
0020 #include <linux/irq.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/i2c.h>
0023 #include <linux/platform_data/i2c-pxa.h>
0024 #include <linux/pwm.h>
0025 #include <linux/pwm_backlight.h>
0026 
0027 #include <asm/mach/map.h>
0028 #include "pxa27x.h"
0029 #include <linux/platform_data/asoc-pxa.h>
0030 #include <linux/platform_data/mmc-pxamci.h>
0031 #include <linux/platform_data/usb-ohci-pxa27x.h>
0032 #include "pcm990_baseboard.h"
0033 #include <linux/platform_data/video-pxafb.h>
0034 
0035 #include "devices.h"
0036 #include "generic.h"
0037 
0038 static unsigned long pcm990_pin_config[] __initdata = {
0039     /* MMC */
0040     GPIO32_MMC_CLK,
0041     GPIO112_MMC_CMD,
0042     GPIO92_MMC_DAT_0,
0043     GPIO109_MMC_DAT_1,
0044     GPIO110_MMC_DAT_2,
0045     GPIO111_MMC_DAT_3,
0046     /* USB */
0047     GPIO88_USBH1_PWR,
0048     GPIO89_USBH1_PEN,
0049     /* PWM0 */
0050     GPIO16_PWM0_OUT,
0051 
0052     /* I2C */
0053     GPIO117_I2C_SCL,
0054     GPIO118_I2C_SDA,
0055 
0056     /* AC97 */
0057     GPIO28_AC97_BITCLK,
0058     GPIO29_AC97_SDATA_IN_0,
0059     GPIO30_AC97_SDATA_OUT,
0060     GPIO31_AC97_SYNC,
0061 };
0062 
0063 static void __iomem *pcm990_cpld_base;
0064 
0065 static u8 pcm990_cpld_readb(unsigned int reg)
0066 {
0067     return readb(pcm990_cpld_base + reg);
0068 }
0069 
0070 static void pcm990_cpld_writeb(u8 value, unsigned int reg)
0071 {
0072     writeb(value, pcm990_cpld_base + reg);
0073 }
0074 
0075 /*
0076  * pcm990_lcd_power - control power supply to the LCD
0077  * @on: 0 = switch off, 1 = switch on
0078  *
0079  * Called by the pxafb driver
0080  */
0081 #ifndef CONFIG_PCM990_DISPLAY_NONE
0082 static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var)
0083 {
0084     if (on) {
0085         /* enable LCD-Latches
0086          * power on LCD
0087          */
0088         pcm990_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON,
0089                 PCM990_CTRL_REG3);
0090     } else {
0091         /* disable LCD-Latches
0092          * power off LCD
0093          */
0094         pcm990_cpld_writeb(0, PCM990_CTRL_REG3);
0095     }
0096 }
0097 #endif
0098 
0099 #if defined(CONFIG_PCM990_DISPLAY_SHARP)
0100 static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = {
0101     .pixclock       = 28000,
0102     .xres           = 640,
0103     .yres           = 480,
0104     .bpp            = 16,
0105     .hsync_len      = 20,
0106     .left_margin        = 103,
0107     .right_margin       = 47,
0108     .vsync_len      = 6,
0109     .upper_margin       = 28,
0110     .lower_margin       = 5,
0111     .sync           = 0,
0112     .cmap_greyscale     = 0,
0113 };
0114 
0115 static struct pxafb_mach_info pcm990_fbinfo __initdata = {
0116     .modes          = &fb_info_sharp_lq084v1dg21,
0117     .num_modes      = 1,
0118     .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
0119     .pxafb_lcd_power    = pcm990_lcd_power,
0120 };
0121 #elif defined(CONFIG_PCM990_DISPLAY_NEC)
0122 struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = {
0123     .pixclock       = 39720,
0124     .xres           = 640,
0125     .yres           = 480,
0126     .bpp            = 16,
0127     .hsync_len      = 32,
0128     .left_margin        = 16,
0129     .right_margin       = 48,
0130     .vsync_len      = 2,
0131     .upper_margin       = 12,
0132     .lower_margin       = 17,
0133     .sync           = 0,
0134     .cmap_greyscale     = 0,
0135 };
0136 
0137 static struct pxafb_mach_info pcm990_fbinfo __initdata = {
0138     .modes          = &fb_info_nec_nl6448bc20_18d,
0139     .num_modes      = 1,
0140     .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
0141     .pxafb_lcd_power    = pcm990_lcd_power,
0142 };
0143 #endif
0144 
0145 static struct pwm_lookup pcm990_pwm_lookup[] = {
0146     PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
0147            PWM_POLARITY_NORMAL),
0148 };
0149 
0150 static struct platform_pwm_backlight_data pcm990_backlight_data = {
0151     .max_brightness = 1023,
0152     .dft_brightness = 1023,
0153 };
0154 
0155 static struct platform_device pcm990_backlight_device = {
0156     .name       = "pwm-backlight",
0157     .dev        = {
0158         .parent = &pxa27x_device_pwm0.dev,
0159         .platform_data = &pcm990_backlight_data,
0160     },
0161 };
0162 
0163 /*
0164  * The PCM-990 development baseboard uses PCM-027's hardware in the
0165  * following way:
0166  *
0167  * - LCD support is in use
0168  *  - GPIO16 is output for back light on/off with PWM
0169  *  - GPIO58 ... GPIO73 are outputs for display data
0170  *  - GPIO74 is output output for LCDFCLK
0171  *  - GPIO75 is output for LCDLCLK
0172  *  - GPIO76 is output for LCDPCLK
0173  *  - GPIO77 is output for LCDBIAS
0174  * - MMC support is in use
0175  *  - GPIO32 is output for MMCCLK
0176  *  - GPIO92 is MMDAT0
0177  *  - GPIO109 is MMDAT1
0178  *  - GPIO110 is MMCS0
0179  *  - GPIO111 is MMCS1
0180  *  - GPIO112 is MMCMD
0181  * - IDE/CF card is in use
0182  *  - GPIO48 is output /POE
0183  *  - GPIO49 is output /PWE
0184  *  - GPIO50 is output /PIOR
0185  *  - GPIO51 is output /PIOW
0186  *  - GPIO54 is output /PCE2
0187  *  - GPIO55 is output /PREG
0188  *  - GPIO56 is input /PWAIT
0189  *  - GPIO57 is output /PIOS16
0190  *  - GPIO79 is output PSKTSEL
0191  *  - GPIO85 is output /PCE1
0192  * - FFUART is in use
0193  *  - GPIO34 is input FFRXD
0194  *  - GPIO35 is input FFCTS
0195  *  - GPIO36 is input FFDCD
0196  *  - GPIO37 is input FFDSR
0197  *  - GPIO38 is input FFRI
0198  *  - GPIO39 is output FFTXD
0199  *  - GPIO40 is output FFDTR
0200  *  - GPIO41 is output FFRTS
0201  * - BTUART is in use
0202  *  - GPIO42 is input BTRXD
0203  *  - GPIO43 is output BTTXD
0204  *  - GPIO44 is input BTCTS
0205  *  - GPIO45 is output BTRTS
0206  * - IRUART is in use
0207  *  - GPIO46 is input STDRXD
0208  *  - GPIO47 is output STDTXD
0209  * - AC97 is in use*)
0210  *  - GPIO28 is input AC97CLK
0211  *  - GPIO29 is input AC97DatIn
0212  *  - GPIO30 is output AC97DatO
0213  *  - GPIO31 is output AC97SYNC
0214  *  - GPIO113 is output AC97_RESET
0215  * - SSP is in use
0216  *  - GPIO23 is output SSPSCLK
0217  *  - GPIO24 is output chip select to Max7301
0218  *  - GPIO25 is output SSPTXD
0219  *  - GPIO26 is input SSPRXD
0220  *  - GPIO27 is input for Max7301 IRQ
0221  *  - GPIO53 is input SSPSYSCLK
0222  * - SSP3 is in use
0223  *  - GPIO81 is output SSPTXD3
0224  *  - GPIO82 is input SSPRXD3
0225  *  - GPIO83 is output SSPSFRM
0226  *  - GPIO84 is output SSPCLK3
0227  *
0228  * Otherwise claimed GPIOs:
0229  * GPIO1 -> IRQ from user switch
0230  * GPIO9 -> IRQ from power management
0231  * GPIO10 -> IRQ from WML9712 AC97 controller
0232  * GPIO11 -> IRQ from IDE controller
0233  * GPIO12 -> IRQ from CF controller
0234  * GPIO13 -> IRQ from CF controller
0235  * GPIO14 -> GPIO free
0236  * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
0237  * GPIO19 -> GPIO free
0238  * GPIO20 -> /SDCS2
0239  * GPIO21 -> /CS3 PC card socket select
0240  * GPIO33 -> /CS5  network controller select
0241  * GPIO78 -> /CS2  (16 bit wide data path)
0242  * GPIO80 -> /CS4  (16 bit wide data path)
0243  * GPIO86 -> GPIO free
0244  * GPIO87 -> GPIO free
0245  * GPIO90 -> LED0 on CPU module
0246  * GPIO91 -> LED1 on CPI module
0247  * GPIO117 -> SCL
0248  * GPIO118 -> SDA
0249  */
0250 
0251 static unsigned long pcm990_irq_enabled;
0252 
0253 static void pcm990_mask_ack_irq(struct irq_data *d)
0254 {
0255     int pcm990_irq = (d->irq - PCM027_IRQ(0));
0256 
0257     pcm990_irq_enabled &= ~(1 << pcm990_irq);
0258 
0259     pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
0260 }
0261 
0262 static void pcm990_unmask_irq(struct irq_data *d)
0263 {
0264     int pcm990_irq = (d->irq - PCM027_IRQ(0));
0265     u8 val;
0266 
0267     /* the irq can be acknowledged only if deasserted, so it's done here */
0268 
0269     pcm990_irq_enabled |= (1 << pcm990_irq);
0270 
0271     val = pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
0272     val |= 1 << pcm990_irq;
0273     pcm990_cpld_writeb(val, PCM990_CTRL_INTSETCLR);
0274 
0275     pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
0276 }
0277 
0278 static struct irq_chip pcm990_irq_chip = {
0279     .irq_mask_ack   = pcm990_mask_ack_irq,
0280     .irq_unmask = pcm990_unmask_irq,
0281 };
0282 
0283 static void pcm990_irq_handler(struct irq_desc *desc)
0284 {
0285     unsigned int irq;
0286     unsigned long pending;
0287 
0288     pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
0289     pending &= pcm990_irq_enabled;
0290 
0291     do {
0292         /* clear our parent IRQ */
0293         desc->irq_data.chip->irq_ack(&desc->irq_data);
0294         if (likely(pending)) {
0295             irq = PCM027_IRQ(0) + __ffs(pending);
0296             generic_handle_irq(irq);
0297         }
0298         pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
0299         pending &= pcm990_irq_enabled;
0300     } while (pending);
0301 }
0302 
0303 static void __init pcm990_init_irq(void)
0304 {
0305     int irq;
0306 
0307     /* setup extra PCM990 irqs */
0308     for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
0309         irq_set_chip_and_handler(irq, &pcm990_irq_chip,
0310                      handle_level_irq);
0311         irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
0312     }
0313 
0314     /* disable all Interrupts */
0315     pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA);
0316     pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR);
0317 
0318     irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
0319     irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
0320 }
0321 
0322 static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
0323             void *data)
0324 {
0325     int err;
0326 
0327     err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, 0,
0328                  "MMC card detect", data);
0329     if (err)
0330         printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
0331                 "card detect IRQ\n");
0332 
0333     return err;
0334 }
0335 
0336 static int pcm990_mci_setpower(struct device *dev, unsigned int vdd)
0337 {
0338     struct pxamci_platform_data *p_d = dev->platform_data;
0339     u8 val;
0340 
0341     val = pcm990_cpld_readb(PCM990_CTRL_REG5);
0342 
0343     if ((1 << vdd) & p_d->ocr_mask)
0344         val |= PCM990_CTRL_MMC2PWR;
0345     else
0346         val &= ~PCM990_CTRL_MMC2PWR;
0347 
0348     pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
0349     return 0;
0350 }
0351 
0352 static void pcm990_mci_exit(struct device *dev, void *data)
0353 {
0354     free_irq(PCM027_MMCDET_IRQ, data);
0355 }
0356 
0357 #define MSECS_PER_JIFFY (1000/HZ)
0358 
0359 static struct pxamci_platform_data pcm990_mci_platform_data = {
0360     .detect_delay_ms    = 250,
0361     .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
0362     .init           = pcm990_mci_init,
0363     .setpower       = pcm990_mci_setpower,
0364     .exit           = pcm990_mci_exit,
0365 };
0366 
0367 static struct pxaohci_platform_data pcm990_ohci_platform_data = {
0368     .port_mode  = PMM_PERPORT_MODE,
0369     .flags      = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
0370     .power_on_delay = 10,
0371 };
0372 
0373 /*
0374  * system init for baseboard usage. Will be called by pcm027 init.
0375  *
0376  * Add platform devices present on this baseboard and init
0377  * them from CPU side as far as required to use them later on
0378  */
0379 void __init pcm990_baseboard_init(void)
0380 {
0381     pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));
0382 
0383     pcm990_cpld_base = ioremap(PCM990_CTRL_PHYS, PCM990_CTRL_SIZE);
0384     if (!pcm990_cpld_base) {
0385         pr_err("pcm990: failed to ioremap cpld\n");
0386         return;
0387     }
0388 
0389     /* register CPLD's IRQ controller */
0390     pcm990_init_irq();
0391 
0392 #ifndef CONFIG_PCM990_DISPLAY_NONE
0393     pxa_set_fb_info(NULL, &pcm990_fbinfo);
0394 #endif
0395     pwm_add_table(pcm990_pwm_lookup, ARRAY_SIZE(pcm990_pwm_lookup));
0396     platform_device_register(&pcm990_backlight_device);
0397 
0398     /* MMC */
0399     pxa_set_mci_info(&pcm990_mci_platform_data);
0400 
0401     /* USB host */
0402     pxa_set_ohci_info(&pcm990_ohci_platform_data);
0403 
0404     pxa_set_i2c_info(NULL);
0405     pxa_set_ac97_info(NULL);
0406 
0407     printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
0408 }