1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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
47 GPIO88_USBH1_PWR,
48 GPIO89_USBH1_PEN,
49
50 GPIO16_PWM0_OUT,
51
52
53 GPIO117_I2C_SCL,
54 GPIO118_I2C_SDA,
55
56
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
77
78
79
80
81#ifndef CONFIG_PCM990_DISPLAY_NONE
82static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var)
83{
84 if (on) {
85
86
87
88 pcm990_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON,
89 PCM990_CTRL_REG3);
90 } else {
91
92
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
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
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
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
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
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
375
376
377
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
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
399 pxa_set_mci_info(&pcm990_mci_platform_data);
400
401
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