Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * linux/arch/arm/mach-pxa/zylonite.c
  3  *
  4  * Support for the PXA3xx Development Platform (aka Zylonite)
  5  *
  6  * Copyright (C) 2006 Marvell International Ltd.
  7  *
  8  * 2007-09-04: eric miao <eric.miao@marvell.com>
  9  *             rewrite to align with latest kernel
 10  *
 11  * This program is free software; you can redistribute it and/or modify
 12  * it under the terms of the GNU General Public License version 2 as
 13  * published by the Free Software Foundation.
 14  */
 15 
 16 #include <linux/module.h>
 17 #include <linux/kernel.h>
 18 #include <linux/interrupt.h>
 19 #include <linux/init.h>
 20 #include <linux/platform_device.h>
 21 
 22 #include <asm/mach-types.h>
 23 #include <asm/mach/arch.h>
 24 #include <asm/hardware.h>
 25 #include <asm/arch/gpio.h>
 26 #include <asm/arch/pxafb.h>
 27 #include <asm/arch/zylonite.h>
 28 #include <asm/arch/mmc.h>
 29 
 30 #include "generic.h"
 31 
 32 #define MAX_SLOTS       3
 33 struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
 34 
 35 int gpio_backlight;
 36 int gpio_eth_irq;
 37 
 38 int lcd_id;
 39 int lcd_orientation;
 40 
 41 static struct resource smc91x_resources[] = {
 42         [0] = {
 43                 .start  = ZYLONITE_ETH_PHYS + 0x300,
 44                 .end    = ZYLONITE_ETH_PHYS + 0xfffff,
 45                 .flags  = IORESOURCE_MEM,
 46         },
 47         [1] = {
 48                 .start  = -1,   /* for run-time assignment */
 49                 .end    = -1,
 50                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 51         }
 52 };
 53 
 54 static struct platform_device smc91x_device = {
 55         .name           = "smc91x",
 56         .id             = 0,
 57         .num_resources  = ARRAY_SIZE(smc91x_resources),
 58         .resource       = smc91x_resources,
 59 };
 60 
 61 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 62 static void zylonite_backlight_power(int on)
 63 {
 64         gpio_set_value(gpio_backlight, on);
 65 }
 66 
 67 static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
 68         .pixclock               = 110000,
 69         .xres                   = 240,
 70         .yres                   = 320,
 71         .bpp                    = 16,
 72         .hsync_len              = 4,
 73         .left_margin            = 6,
 74         .right_margin           = 4,
 75         .vsync_len              = 2,
 76         .upper_margin           = 2,
 77         .lower_margin           = 3,
 78         .sync                   = FB_SYNC_VERT_HIGH_ACT,
 79 };
 80 
 81 static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
 82         .pixclock               = 50000,
 83         .xres                   = 640,
 84         .yres                   = 480,
 85         .bpp                    = 16,
 86         .hsync_len              = 1,
 87         .left_margin            = 0x9f,
 88         .right_margin           = 1,
 89         .vsync_len              = 44,
 90         .upper_margin           = 0,
 91         .lower_margin           = 0,
 92         .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
 93 };
 94 
 95 static struct pxafb_mach_info zylonite_toshiba_lcd_info = {
 96         .num_modes              = 1,
 97         .lccr0                  = LCCR0_Act,
 98         .lccr3                  = LCCR3_PCP,
 99         .pxafb_backlight_power  = zylonite_backlight_power,
100 };
101 
102 static struct pxafb_mode_info sharp_ls037_modes[] = {
103         [0] = {
104                 .pixclock       = 158000,
105                 .xres           = 240,
106                 .yres           = 320,
107                 .bpp            = 16,
108                 .hsync_len      = 4,
109                 .left_margin    = 39,
110                 .right_margin   = 39,
111                 .vsync_len      = 1,
112                 .upper_margin   = 2,
113                 .lower_margin   = 3,
114                 .sync           = 0,
115         },
116         [1] = {
117                 .pixclock       = 39700,
118                 .xres           = 480,
119                 .yres           = 640,
120                 .bpp            = 16,
121                 .hsync_len      = 8,
122                 .left_margin    = 81,
123                 .right_margin   = 81,
124                 .vsync_len      = 1,
125                 .upper_margin   = 2,
126                 .lower_margin   = 7,
127                 .sync           = 0,
128         },
129 };
130 
131 static struct pxafb_mach_info zylonite_sharp_lcd_info = {
132         .modes                  = sharp_ls037_modes,
133         .num_modes              = 2,
134         .lccr0                  = LCCR0_Act,
135         .lccr3                  = LCCR3_PCP | LCCR3_HSP | LCCR3_VSP,
136         .pxafb_backlight_power  = zylonite_backlight_power,
137 };
138 
139 static void __init zylonite_init_lcd(void)
140 {
141         /* backlight GPIO: output, default on */
142         gpio_direction_output(gpio_backlight, 1);
143 
144         if (lcd_id & 0x20) {
145                 set_pxa_fb_info(&zylonite_sharp_lcd_info);
146                 return;
147         }
148 
149         /* legacy LCD panels, it would be handy here if LCD panel type can
150          * be decided at run-time
151          */
152         if (1)
153                 zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode;
154         else
155                 zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
156 
157         set_pxa_fb_info(&zylonite_toshiba_lcd_info);
158 }
159 #else
160 static inline void zylonite_init_lcd(void) {}
161 #endif
162 
163 #if defined(CONFIG_MMC)
164 static int zylonite_mci_ro(struct device *dev)
165 {
166         struct platform_device *pdev = to_platform_device(dev);
167 
168         return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
169 }
170 
171 static int zylonite_mci_init(struct device *dev,
172                              irq_handler_t zylonite_detect_int,
173                              void *data)
174 {
175         struct platform_device *pdev = to_platform_device(dev);
176         int err, cd_irq, gpio_cd, gpio_wp;
177 
178         cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
179         gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
180         gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
181 
182         /*
183          * setup GPIO for Zylonite MMC controller
184          */
185         err = gpio_request(gpio_cd, "mmc card detect");
186         if (err)
187                 goto err_request_cd;
188         gpio_direction_input(gpio_cd);
189 
190         err = gpio_request(gpio_wp, "mmc write protect");
191         if (err)
192                 goto err_request_wp;
193         gpio_direction_input(gpio_wp);
194 
195         err = request_irq(cd_irq, zylonite_detect_int,
196                           IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
197                           "MMC card detect", data);
198         if (err) {
199                 printk(KERN_ERR "%s: MMC/SD/SDIO: "
200                                 "can't request card detect IRQ\n", __func__);
201                 goto err_request_irq;
202         }
203 
204         return 0;
205 
206 err_request_irq:
207         gpio_free(gpio_wp);
208 err_request_wp:
209         gpio_free(gpio_cd);
210 err_request_cd:
211         return err;
212 }
213 
214 static void zylonite_mci_exit(struct device *dev, void *data)
215 {
216         struct platform_device *pdev = to_platform_device(dev);
217         int cd_irq, gpio_cd, gpio_wp;
218 
219         cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
220         gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
221         gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
222 
223         free_irq(cd_irq, data);
224         gpio_free(gpio_cd);
225         gpio_free(gpio_wp);
226 }
227 
228 static struct pxamci_platform_data zylonite_mci_platform_data = {
229         .detect_delay   = 20,
230         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
231         .init           = zylonite_mci_init,
232         .exit           = zylonite_mci_exit,
233         .get_ro         = zylonite_mci_ro,
234 };
235 
236 static struct pxamci_platform_data zylonite_mci2_platform_data = {
237         .detect_delay   = 20,
238         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
239 };
240 
241 static void __init zylonite_init_mmc(void)
242 {
243         pxa_set_mci_info(&zylonite_mci_platform_data);
244         pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
245         if (cpu_is_pxa310())
246                 pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
247 }
248 #else
249 static inline void zylonite_init_mmc(void) {}
250 #endif
251 
252 static void __init zylonite_init(void)
253 {
254         /* board-processor specific initialization */
255         zylonite_pxa300_init();
256         zylonite_pxa320_init();
257 
258         /*
259          * Note: We depend that the bootloader set
260          * the correct value to MSC register for SMC91x.
261          */
262         smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
263         smc91x_resources[1].end   = gpio_to_irq(gpio_eth_irq);
264         platform_device_register(&smc91x_device);
265 
266         zylonite_init_lcd();
267         zylonite_init_mmc();
268 }
269 
270 MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
271         .phys_io        = 0x40000000,
272         .boot_params    = 0xa0000100,
273         .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
274         .map_io         = pxa_map_io,
275         .init_irq       = pxa3xx_init_irq,
276         .timer          = &pxa_timer,
277         .init_machine   = zylonite_init,
278 MACHINE_END
279 
  This page was automatically generated by the LXR engine.