1 // SPDX-License-Identifier: GPL-2.0-only
3 * arch/arm/mach-pxa/pcm990-baseboard.c
4 * Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
7 * http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
8 * for additional hardware info
10 * Author: Juergen Kilb
11 * Created: April 05, 2005
12 * Copyright: Phytec Messtechnik GmbH
13 * e-Mail: armlinux@phytec.de
15 * based on Intel Mainstone Board
17 * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
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>
27 #include <asm/mach/map.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>
38 static unsigned long pcm990_pin_config
[] __initdata
= {
58 GPIO29_AC97_SDATA_IN_0
,
59 GPIO30_AC97_SDATA_OUT
,
63 static void __iomem
*pcm990_cpld_base
;
65 static u8
pcm990_cpld_readb(unsigned int reg
)
67 return readb(pcm990_cpld_base
+ reg
);
70 static void pcm990_cpld_writeb(u8 value
, unsigned int reg
)
72 writeb(value
, pcm990_cpld_base
+ reg
);
76 * pcm990_lcd_power - control power supply to the LCD
77 * @on: 0 = switch off, 1 = switch on
79 * Called by the pxafb driver
81 #ifndef CONFIG_PCM990_DISPLAY_NONE
82 static void pcm990_lcd_power(int on
, struct fb_var_screeninfo
*var
)
88 pcm990_cpld_writeb(PCM990_CTRL_LCDPWR
+ PCM990_CTRL_LCDON
,
91 /* disable LCD-Latches
94 pcm990_cpld_writeb(0, PCM990_CTRL_REG3
);
99 #if defined(CONFIG_PCM990_DISPLAY_SHARP)
100 static struct pxafb_mode_info fb_info_sharp_lq084v1dg21
= {
115 static struct pxafb_mach_info pcm990_fbinfo __initdata
= {
116 .modes
= &fb_info_sharp_lq084v1dg21
,
118 .lcd_conn
= LCD_COLOR_TFT_16BPP
| LCD_PCLK_EDGE_FALL
,
119 .pxafb_lcd_power
= pcm990_lcd_power
,
121 #elif defined(CONFIG_PCM990_DISPLAY_NEC)
122 struct pxafb_mode_info fb_info_nec_nl6448bc20_18d
= {
137 static struct pxafb_mach_info pcm990_fbinfo __initdata
= {
138 .modes
= &fb_info_nec_nl6448bc20_18d
,
140 .lcd_conn
= LCD_COLOR_TFT_16BPP
| LCD_PCLK_EDGE_FALL
,
141 .pxafb_lcd_power
= pcm990_lcd_power
,
145 static struct pwm_lookup pcm990_pwm_lookup
[] = {
146 PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL
, 78770,
147 PWM_POLARITY_NORMAL
),
150 static struct platform_pwm_backlight_data pcm990_backlight_data
= {
151 .max_brightness
= 1023,
152 .dft_brightness
= 1023,
155 static struct platform_device pcm990_backlight_device
= {
156 .name
= "pwm-backlight",
158 .parent
= &pxa27x_device_pwm0
.dev
,
159 .platform_data
= &pcm990_backlight_data
,
164 * The PCM-990 development baseboard uses PCM-027's hardware in the
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
177 * - GPIO109 is MMDAT1
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
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
202 * - GPIO42 is input BTRXD
203 * - GPIO43 is output BTTXD
204 * - GPIO44 is input BTCTS
205 * - GPIO45 is output BTRTS
207 * - GPIO46 is input STDRXD
208 * - GPIO47 is output STDTXD
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
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
223 * - GPIO81 is output SSPTXD3
224 * - GPIO82 is input SSPRXD3
225 * - GPIO83 is output SSPSFRM
226 * - GPIO84 is output SSPCLK3
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
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
251 static unsigned long pcm990_irq_enabled
;
253 static void pcm990_mask_ack_irq(struct irq_data
*d
)
255 int pcm990_irq
= (d
->irq
- PCM027_IRQ(0));
257 pcm990_irq_enabled
&= ~(1 << pcm990_irq
);
259 pcm990_cpld_writeb(pcm990_irq_enabled
, PCM990_CTRL_INTMSKENA
);
262 static void pcm990_unmask_irq(struct irq_data
*d
)
264 int pcm990_irq
= (d
->irq
- PCM027_IRQ(0));
267 /* the irq can be acknowledged only if deasserted, so it's done here */
269 pcm990_irq_enabled
|= (1 << pcm990_irq
);
271 val
= pcm990_cpld_readb(PCM990_CTRL_INTSETCLR
);
272 val
|= 1 << pcm990_irq
;
273 pcm990_cpld_writeb(val
, PCM990_CTRL_INTSETCLR
);
275 pcm990_cpld_writeb(pcm990_irq_enabled
, PCM990_CTRL_INTMSKENA
);
278 static struct irq_chip pcm990_irq_chip
= {
279 .irq_mask_ack
= pcm990_mask_ack_irq
,
280 .irq_unmask
= pcm990_unmask_irq
,
283 static void pcm990_irq_handler(struct irq_desc
*desc
)
286 unsigned long pending
;
288 pending
= ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR
);
289 pending
&= pcm990_irq_enabled
;
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
);
298 pending
= ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR
);
299 pending
&= pcm990_irq_enabled
;
303 static void __init
pcm990_init_irq(void)
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
,
311 irq_clear_status_flags(irq
, IRQ_NOREQUEST
| IRQ_NOPROBE
);
314 /* disable all Interrupts */
315 pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA
);
316 pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR
);
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
);
322 static int pcm990_mci_init(struct device
*dev
, irq_handler_t mci_detect_int
,
327 err
= request_irq(PCM027_MMCDET_IRQ
, mci_detect_int
, 0,
328 "MMC card detect", data
);
330 printk(KERN_ERR
"pcm990_mci_init: MMC/SD: can't request MMC "
331 "card detect IRQ\n");
336 static int pcm990_mci_setpower(struct device
*dev
, unsigned int vdd
)
338 struct pxamci_platform_data
*p_d
= dev
->platform_data
;
341 val
= pcm990_cpld_readb(PCM990_CTRL_REG5
);
343 if ((1 << vdd
) & p_d
->ocr_mask
)
344 val
|= PCM990_CTRL_MMC2PWR
;
346 val
&= ~PCM990_CTRL_MMC2PWR
;
348 pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR
, PCM990_CTRL_REG5
);
352 static void pcm990_mci_exit(struct device
*dev
, void *data
)
354 free_irq(PCM027_MMCDET_IRQ
, data
);
357 #define MSECS_PER_JIFFY (1000/HZ)
359 static 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
,
367 static 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,
374 * system init for baseboard usage. Will be called by pcm027 init.
376 * Add platform devices present on this baseboard and init
377 * them from CPU side as far as required to use them later on
379 void __init
pcm990_baseboard_init(void)
381 pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config
));
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");
389 /* register CPLD's IRQ controller */
392 #ifndef CONFIG_PCM990_DISPLAY_NONE
393 pxa_set_fb_info(NULL
, &pcm990_fbinfo
);
395 pwm_add_table(pcm990_pwm_lookup
, ARRAY_SIZE(pcm990_pwm_lookup
));
396 platform_device_register(&pcm990_backlight_device
);
399 pxa_set_mci_info(&pcm990_mci_platform_data
);
402 pxa_set_ohci_info(&pcm990_ohci_platform_data
);
404 pxa_set_i2c_info(NULL
);
405 pxa_set_ac97_info(NULL
);
407 printk(KERN_INFO
"PCM-990 Evaluation baseboard initialized\n");