0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/init.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/irq.h>
0018 #include <linux/leds.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/fb.h>
0021
0022 #include <asm/setup.h>
0023 #include <asm/memory.h>
0024 #include <asm/mach-types.h>
0025 #include <asm/irq.h>
0026
0027 #include <asm/mach/arch.h>
0028 #include <asm/mach/map.h>
0029
0030 #include "pxa25x.h"
0031 #include "idp.h"
0032 #include <linux/platform_data/video-pxafb.h>
0033 #include <linux/platform_data/mmc-pxamci.h>
0034 #include <linux/smc91x.h>
0035
0036 #include "generic.h"
0037 #include "devices.h"
0038
0039
0040
0041
0042
0043
0044 static unsigned long idp_pin_config[] __initdata = {
0045
0046 GPIOxx_LCD_DSTN_16BPP,
0047
0048
0049 GPIO42_BTUART_RXD,
0050 GPIO43_BTUART_TXD,
0051 GPIO44_BTUART_CTS,
0052 GPIO45_BTUART_RTS,
0053
0054
0055 GPIO46_STUART_RXD,
0056 GPIO47_STUART_TXD,
0057
0058
0059 GPIO6_MMC_CLK,
0060 GPIO8_MMC_CS0,
0061
0062
0063 GPIO33_nCS_5,
0064 GPIO4_GPIO,
0065 };
0066
0067 static struct resource smc91x_resources[] = {
0068 [0] = {
0069 .start = (IDP_ETH_PHYS + 0x300),
0070 .end = (IDP_ETH_PHYS + 0xfffff),
0071 .flags = IORESOURCE_MEM,
0072 },
0073 [1] = {
0074 .start = PXA_GPIO_TO_IRQ(4),
0075 .end = PXA_GPIO_TO_IRQ(4),
0076 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
0077 }
0078 };
0079
0080 static struct smc91x_platdata smc91x_platdata = {
0081 .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
0082 SMC91X_USE_DMA | SMC91X_NOWAIT,
0083 .pxa_u16_align4 = true,
0084 };
0085
0086 static struct platform_device smc91x_device = {
0087 .name = "smc91x",
0088 .id = 0,
0089 .num_resources = ARRAY_SIZE(smc91x_resources),
0090 .resource = smc91x_resources,
0091 .dev.platform_data = &smc91x_platdata,
0092 };
0093
0094 static void idp_backlight_power(int on)
0095 {
0096 if (on) {
0097 IDP_CPLD_LCD |= (1<<1);
0098 } else {
0099 IDP_CPLD_LCD &= ~(1<<1);
0100 }
0101 }
0102
0103 static void idp_vlcd(int on)
0104 {
0105 if (on) {
0106 IDP_CPLD_LCD |= (1<<2);
0107 } else {
0108 IDP_CPLD_LCD &= ~(1<<2);
0109 }
0110 }
0111
0112 static void idp_lcd_power(int on, struct fb_var_screeninfo *var)
0113 {
0114 if (on) {
0115 IDP_CPLD_LCD |= (1<<0);
0116 } else {
0117 IDP_CPLD_LCD &= ~(1<<0);
0118 }
0119
0120
0121
0122
0123
0124
0125
0126 idp_vlcd(on);
0127 }
0128
0129 static struct pxafb_mode_info sharp_lm8v31_mode = {
0130 .pixclock = 270000,
0131 .xres = 640,
0132 .yres = 480,
0133 .bpp = 16,
0134 .hsync_len = 1,
0135 .left_margin = 3,
0136 .right_margin = 3,
0137 .vsync_len = 1,
0138 .upper_margin = 0,
0139 .lower_margin = 0,
0140 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
0141 .cmap_greyscale = 0,
0142 };
0143
0144 static struct pxafb_mach_info sharp_lm8v31 = {
0145 .modes = &sharp_lm8v31_mode,
0146 .num_modes = 1,
0147 .cmap_inverse = 0,
0148 .cmap_static = 0,
0149 .lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
0150 LCD_AC_BIAS_FREQ(255),
0151 .pxafb_backlight_power = &idp_backlight_power,
0152 .pxafb_lcd_power = &idp_lcd_power
0153 };
0154
0155 static struct pxamci_platform_data idp_mci_platform_data = {
0156 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
0157 };
0158
0159 static void __init idp_init(void)
0160 {
0161 printk("idp_init()\n");
0162
0163 pxa2xx_mfp_config(ARRAY_AND_SIZE(idp_pin_config));
0164 pxa_set_ffuart_info(NULL);
0165 pxa_set_btuart_info(NULL);
0166 pxa_set_stuart_info(NULL);
0167
0168 platform_device_register(&smc91x_device);
0169
0170 pxa_set_fb_info(NULL, &sharp_lm8v31);
0171 pxa_set_mci_info(&idp_mci_platform_data);
0172 }
0173
0174 static struct map_desc idp_io_desc[] __initdata = {
0175 {
0176 .virtual = IDP_COREVOLT_VIRT,
0177 .pfn = __phys_to_pfn(IDP_COREVOLT_PHYS),
0178 .length = IDP_COREVOLT_SIZE,
0179 .type = MT_DEVICE
0180 }, {
0181 .virtual = IDP_CPLD_VIRT,
0182 .pfn = __phys_to_pfn(IDP_CPLD_PHYS),
0183 .length = IDP_CPLD_SIZE,
0184 .type = MT_DEVICE
0185 }
0186 };
0187
0188 static void __init idp_map_io(void)
0189 {
0190 pxa25x_map_io();
0191 iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
0192 }
0193
0194
0195 #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
0196 struct idp_led {
0197 struct led_classdev cdev;
0198 u8 mask;
0199 };
0200
0201
0202
0203
0204
0205 static const struct {
0206 const char *name;
0207 const char *trigger;
0208 } idp_leds[] = {
0209 { "idp:green", "heartbeat", },
0210 { "idp:red", "cpu0", },
0211 };
0212
0213 static void idp_led_set(struct led_classdev *cdev,
0214 enum led_brightness b)
0215 {
0216 struct idp_led *led = container_of(cdev,
0217 struct idp_led, cdev);
0218 u32 reg = IDP_CPLD_LED_CONTROL;
0219
0220 if (b != LED_OFF)
0221 reg &= ~led->mask;
0222 else
0223 reg |= led->mask;
0224
0225 IDP_CPLD_LED_CONTROL = reg;
0226 }
0227
0228 static enum led_brightness idp_led_get(struct led_classdev *cdev)
0229 {
0230 struct idp_led *led = container_of(cdev,
0231 struct idp_led, cdev);
0232
0233 return (IDP_CPLD_LED_CONTROL & led->mask) ? LED_OFF : LED_FULL;
0234 }
0235
0236 static int __init idp_leds_init(void)
0237 {
0238 int i;
0239
0240 if (!machine_is_pxa_idp())
0241 return -ENODEV;
0242
0243 for (i = 0; i < ARRAY_SIZE(idp_leds); i++) {
0244 struct idp_led *led;
0245
0246 led = kzalloc(sizeof(*led), GFP_KERNEL);
0247 if (!led)
0248 break;
0249
0250 led->cdev.name = idp_leds[i].name;
0251 led->cdev.brightness_set = idp_led_set;
0252 led->cdev.brightness_get = idp_led_get;
0253 led->cdev.default_trigger = idp_leds[i].trigger;
0254
0255 if (i == 0)
0256 led->mask = IDP_HB_LED;
0257 else
0258 led->mask = IDP_BUSY_LED;
0259
0260 if (led_classdev_register(NULL, &led->cdev) < 0) {
0261 kfree(led);
0262 break;
0263 }
0264 }
0265
0266 return 0;
0267 }
0268
0269
0270
0271
0272
0273 fs_initcall(idp_leds_init);
0274 #endif
0275
0276 MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
0277
0278 .map_io = idp_map_io,
0279 .nr_irqs = PXA_NR_IRQS,
0280 .init_irq = pxa25x_init_irq,
0281 .handle_irq = pxa25x_handle_irq,
0282 .init_time = pxa_timer_init,
0283 .init_machine = idp_init,
0284 .restart = pxa_restart,
0285 MACHINE_END