diff options
author | Eric Miao <eric.miao@marvell.com> | 2008-08-28 20:09:48 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-09-23 17:04:36 -0400 |
commit | edb403fbfb0ad56e62d8ebbecc3b846487020e0f (patch) | |
tree | f0b10d6738aef50ad886e09d6735b1398875c989 /arch | |
parent | 9ae808d8b1d8a99832798a6699b4cb7f51bfc872 (diff) |
[ARM] pxa/corgi: use SPI-based driver for ads7846, corgi-lcd and max1111
Signed-off-by: Eric Miao <eric.miao@marvell.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/corgi.c | 293 |
2 files changed, 132 insertions, 163 deletions
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index b069dcbb764c..ced2a679d08a 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -28,7 +28,7 @@ obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o | |||
28 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o | 28 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o |
29 | obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o | 29 | obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o |
30 | obj-$(CONFIG_MACH_COLIBRI) += colibri.o | 30 | obj-$(CONFIG_MACH_COLIBRI) += colibri.o |
31 | obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o | 31 | obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o sharpsl_pm.o corgi_pm.o |
32 | obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o | 32 | obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o |
33 | obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o | 33 | obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o |
34 | obj-$(CONFIG_MACH_POODLE) += poodle.o | 34 | obj-$(CONFIG_MACH_POODLE) += poodle.o |
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 14155fc49a12..68765636bfce 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
@@ -22,6 +22,9 @@ | |||
22 | #include <linux/pm.h> | 22 | #include <linux/pm.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/backlight.h> | 24 | #include <linux/backlight.h> |
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/spi/ads7846.h> | ||
27 | #include <linux/spi/corgi_lcd.h> | ||
25 | #include <video/w100fb.h> | 28 | #include <video/w100fb.h> |
26 | 29 | ||
27 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
@@ -43,6 +46,7 @@ | |||
43 | #include <mach/irda.h> | 46 | #include <mach/irda.h> |
44 | #include <mach/mmc.h> | 47 | #include <mach/mmc.h> |
45 | #include <mach/udc.h> | 48 | #include <mach/udc.h> |
49 | #include <mach/pxa2xx_spi.h> | ||
46 | #include <mach/corgi.h> | 50 | #include <mach/corgi.h> |
47 | #include <mach/sharpsl.h> | 51 | #include <mach/sharpsl.h> |
48 | 52 | ||
@@ -151,53 +155,6 @@ static struct scoop_pcmcia_config corgi_pcmcia_config = { | |||
151 | 155 | ||
152 | EXPORT_SYMBOL(corgiscoop_device); | 156 | EXPORT_SYMBOL(corgiscoop_device); |
153 | 157 | ||
154 | |||
155 | /* | ||
156 | * Corgi SSP Device | ||
157 | * | ||
158 | * Set the parent as the scoop device because a lot of SSP devices | ||
159 | * also use scoop functions and this makes the power up/down order | ||
160 | * work correctly. | ||
161 | */ | ||
162 | struct platform_device corgissp_device = { | ||
163 | .name = "corgi-ssp", | ||
164 | .dev = { | ||
165 | .parent = &corgiscoop_device.dev, | ||
166 | }, | ||
167 | .id = -1, | ||
168 | }; | ||
169 | |||
170 | struct corgissp_machinfo corgi_ssp_machinfo = { | ||
171 | .port = 1, | ||
172 | .cs_lcdcon = CORGI_GPIO_LCDCON_CS, | ||
173 | .cs_ads7846 = CORGI_GPIO_ADS7846_CS, | ||
174 | .cs_max1111 = CORGI_GPIO_MAX1111_CS, | ||
175 | .clk_lcdcon = 76, | ||
176 | .clk_ads7846 = 2, | ||
177 | .clk_max1111 = 8, | ||
178 | }; | ||
179 | |||
180 | |||
181 | /* | ||
182 | * LCD/Framebuffer | ||
183 | */ | ||
184 | static void w100_lcdtg_suspend(struct w100fb_par *par) | ||
185 | { | ||
186 | corgi_lcdtg_suspend(); | ||
187 | } | ||
188 | |||
189 | static void w100_lcdtg_init(struct w100fb_par *par) | ||
190 | { | ||
191 | corgi_lcdtg_hw_init(par->xres); | ||
192 | } | ||
193 | |||
194 | |||
195 | static struct w100_tg_info corgi_lcdtg_info = { | ||
196 | .change = w100_lcdtg_init, | ||
197 | .suspend = w100_lcdtg_suspend, | ||
198 | .resume = w100_lcdtg_init, | ||
199 | }; | ||
200 | |||
201 | static struct w100_mem_info corgi_fb_mem = { | 158 | static struct w100_mem_info corgi_fb_mem = { |
202 | .ext_cntl = 0x00040003, | 159 | .ext_cntl = 0x00040003, |
203 | .sdram_mode_reg = 0x00650021, | 160 | .sdram_mode_reg = 0x00650021, |
@@ -276,7 +233,6 @@ static struct w100_mode corgi_fb_modes[] = { | |||
276 | }; | 233 | }; |
277 | 234 | ||
278 | static struct w100fb_mach_info corgi_fb_info = { | 235 | static struct w100fb_mach_info corgi_fb_info = { |
279 | .tg = &corgi_lcdtg_info, | ||
280 | .init_mode = INIT_MODE_ROTATED, | 236 | .init_mode = INIT_MODE_ROTATED, |
281 | .mem = &corgi_fb_mem, | 237 | .mem = &corgi_fb_mem, |
282 | .regs = &corgi_fb_regs, | 238 | .regs = &corgi_fb_regs, |
@@ -302,60 +258,10 @@ static struct platform_device corgifb_device = { | |||
302 | .resource = corgi_fb_resources, | 258 | .resource = corgi_fb_resources, |
303 | .dev = { | 259 | .dev = { |
304 | .platform_data = &corgi_fb_info, | 260 | .platform_data = &corgi_fb_info, |
305 | .parent = &corgissp_device.dev, | ||
306 | }, | 261 | }, |
307 | 262 | ||
308 | }; | 263 | }; |
309 | 264 | ||
310 | |||
311 | /* | ||
312 | * Corgi Backlight Device | ||
313 | */ | ||
314 | static void corgi_bl_kick_battery(void) | ||
315 | { | ||
316 | void (*kick_batt)(void); | ||
317 | |||
318 | kick_batt = symbol_get(sharpsl_battery_kick); | ||
319 | if (kick_batt) { | ||
320 | kick_batt(); | ||
321 | symbol_put(sharpsl_battery_kick); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | static void corgi_bl_set_intensity(int intensity) | ||
326 | { | ||
327 | if (intensity > 0x10) | ||
328 | intensity += 0x10; | ||
329 | |||
330 | /* Bits 0-4 are accessed via the SSP interface */ | ||
331 | corgi_ssp_blduty_set(intensity & 0x1f); | ||
332 | |||
333 | /* Bit 5 is via SCOOP */ | ||
334 | if (intensity & 0x0020) | ||
335 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); | ||
336 | else | ||
337 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); | ||
338 | } | ||
339 | |||
340 | static struct generic_bl_info corgi_bl_machinfo = { | ||
341 | .name = "corgi-bl", | ||
342 | .max_intensity = 0x2f, | ||
343 | .default_intensity = 0x1f, | ||
344 | .limit_mask = 0x0b, | ||
345 | .set_bl_intensity = corgi_bl_set_intensity, | ||
346 | .kick_battery = corgi_bl_kick_battery, | ||
347 | }; | ||
348 | |||
349 | static struct platform_device corgibl_device = { | ||
350 | .name = "generic-bl", | ||
351 | .dev = { | ||
352 | .parent = &corgifb_device.dev, | ||
353 | .platform_data = &corgi_bl_machinfo, | ||
354 | }, | ||
355 | .id = -1, | ||
356 | }; | ||
357 | |||
358 | |||
359 | /* | 265 | /* |
360 | * Corgi Keyboard Device | 266 | * Corgi Keyboard Device |
361 | */ | 267 | */ |
@@ -373,66 +279,6 @@ static struct platform_device corgiled_device = { | |||
373 | .id = -1, | 279 | .id = -1, |
374 | }; | 280 | }; |
375 | 281 | ||
376 | |||
377 | /* | ||
378 | * Corgi Touch Screen Device | ||
379 | */ | ||
380 | static unsigned long (*get_hsync_invperiod)(struct device *dev); | ||
381 | |||
382 | static void inline sharpsl_wait_sync(int gpio) | ||
383 | { | ||
384 | while((GPLR(gpio) & GPIO_bit(gpio)) == 0); | ||
385 | while((GPLR(gpio) & GPIO_bit(gpio)) != 0); | ||
386 | } | ||
387 | |||
388 | static unsigned long corgi_get_hsync_invperiod(void) | ||
389 | { | ||
390 | if (!get_hsync_invperiod) | ||
391 | get_hsync_invperiod = symbol_get(w100fb_get_hsynclen); | ||
392 | if (!get_hsync_invperiod) | ||
393 | return 0; | ||
394 | |||
395 | return get_hsync_invperiod(&corgifb_device.dev); | ||
396 | } | ||
397 | |||
398 | static void corgi_put_hsync(void) | ||
399 | { | ||
400 | if (get_hsync_invperiod) | ||
401 | symbol_put(w100fb_get_hsynclen); | ||
402 | get_hsync_invperiod = NULL; | ||
403 | } | ||
404 | |||
405 | static void corgi_wait_hsync(void) | ||
406 | { | ||
407 | sharpsl_wait_sync(CORGI_GPIO_HSYNC); | ||
408 | } | ||
409 | |||
410 | static struct resource corgits_resources[] = { | ||
411 | [0] = { | ||
412 | .start = CORGI_IRQ_GPIO_TP_INT, | ||
413 | .end = CORGI_IRQ_GPIO_TP_INT, | ||
414 | .flags = IORESOURCE_IRQ, | ||
415 | }, | ||
416 | }; | ||
417 | |||
418 | static struct corgits_machinfo corgi_ts_machinfo = { | ||
419 | .get_hsync_invperiod = corgi_get_hsync_invperiod, | ||
420 | .put_hsync = corgi_put_hsync, | ||
421 | .wait_hsync = corgi_wait_hsync, | ||
422 | }; | ||
423 | |||
424 | static struct platform_device corgits_device = { | ||
425 | .name = "corgi-ts", | ||
426 | .dev = { | ||
427 | .parent = &corgissp_device.dev, | ||
428 | .platform_data = &corgi_ts_machinfo, | ||
429 | }, | ||
430 | .id = -1, | ||
431 | .num_resources = ARRAY_SIZE(corgits_resources), | ||
432 | .resource = corgits_resources, | ||
433 | }; | ||
434 | |||
435 | |||
436 | /* | 282 | /* |
437 | * MMC/SD Device | 283 | * MMC/SD Device |
438 | * | 284 | * |
@@ -555,14 +401,137 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { | |||
555 | .gpio_pullup = CORGI_GPIO_USB_PULLUP, | 401 | .gpio_pullup = CORGI_GPIO_USB_PULLUP, |
556 | }; | 402 | }; |
557 | 403 | ||
404 | #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MASTER) | ||
405 | static struct pxa2xx_spi_master corgi_spi_info = { | ||
406 | .num_chipselect = 3, | ||
407 | }; | ||
408 | |||
409 | static struct ads7846_platform_data corgi_ads7846_info = { | ||
410 | .model = 7846, | ||
411 | .vref_delay_usecs = 100, | ||
412 | .x_plate_ohms = 419, | ||
413 | .y_plate_ohms = 486, | ||
414 | .gpio_pendown = CORGI_GPIO_TP_INT, | ||
415 | }; | ||
416 | |||
417 | static void corgi_ads7846_cs(u32 command) | ||
418 | { | ||
419 | gpio_set_value(CORGI_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT)); | ||
420 | } | ||
421 | |||
422 | static struct pxa2xx_spi_chip corgi_ads7846_chip = { | ||
423 | .cs_control = corgi_ads7846_cs, | ||
424 | }; | ||
425 | |||
426 | static void corgi_notify_intensity(int intensity) | ||
427 | { | ||
428 | /* Bit 5 is via SCOOP */ | ||
429 | if (intensity & 0x0020) | ||
430 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); | ||
431 | else | ||
432 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); | ||
433 | } | ||
434 | |||
435 | static void corgi_bl_kick_battery(void) | ||
436 | { | ||
437 | void (*kick_batt)(void); | ||
438 | |||
439 | kick_batt = symbol_get(sharpsl_battery_kick); | ||
440 | if (kick_batt) { | ||
441 | kick_batt(); | ||
442 | symbol_put(sharpsl_battery_kick); | ||
443 | } | ||
444 | } | ||
445 | |||
446 | static struct corgi_lcd_platform_data corgi_lcdcon_info = { | ||
447 | .init_mode = CORGI_LCD_MODE_VGA, | ||
448 | .max_intensity = 0x2f, | ||
449 | .default_intensity = 0x1f, | ||
450 | .limit_mask = 0x0b, | ||
451 | .notify = corgi_notify_intensity, | ||
452 | .kick_battery = corgi_bl_kick_battery, | ||
453 | }; | ||
454 | |||
455 | static void corgi_lcdcon_cs(u32 command) | ||
456 | { | ||
457 | gpio_set_value(CORGI_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT)); | ||
458 | } | ||
459 | |||
460 | static struct pxa2xx_spi_chip corgi_lcdcon_chip = { | ||
461 | .cs_control = corgi_lcdcon_cs, | ||
462 | }; | ||
463 | |||
464 | static void corgi_max1111_cs(u32 command) | ||
465 | { | ||
466 | gpio_set_value(CORGI_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT)); | ||
467 | } | ||
468 | |||
469 | static struct pxa2xx_spi_chip corgi_max1111_chip = { | ||
470 | .cs_control = corgi_max1111_cs, | ||
471 | }; | ||
472 | |||
473 | static struct spi_board_info corgi_spi_devices[] = { | ||
474 | { | ||
475 | .modalias = "ads7846", | ||
476 | .max_speed_hz = 1200000, | ||
477 | .bus_num = 1, | ||
478 | .chip_select = 0, | ||
479 | .platform_data = &corgi_ads7846_info, | ||
480 | .controller_data= &corgi_ads7846_chip, | ||
481 | .irq = gpio_to_irq(CORGI_GPIO_TP_INT), | ||
482 | }, { | ||
483 | .modalias = "corgi-lcd", | ||
484 | .max_speed_hz = 50000, | ||
485 | .bus_num = 1, | ||
486 | .chip_select = 1, | ||
487 | .platform_data = &corgi_lcdcon_info, | ||
488 | .controller_data= &corgi_lcdcon_chip, | ||
489 | }, { | ||
490 | .modalias = "max1111", | ||
491 | .max_speed_hz = 450000, | ||
492 | .bus_num = 1, | ||
493 | .chip_select = 2, | ||
494 | .controller_data= &corgi_max1111_chip, | ||
495 | }, | ||
496 | }; | ||
497 | |||
498 | static void __init corgi_init_spi(void) | ||
499 | { | ||
500 | int err; | ||
501 | |||
502 | err = gpio_request(CORGI_GPIO_ADS7846_CS, "ADS7846_CS"); | ||
503 | if (err) | ||
504 | return; | ||
505 | |||
506 | err = gpio_request(CORGI_GPIO_LCDCON_CS, "LCDCON_CS"); | ||
507 | if (err) | ||
508 | goto err_free_1; | ||
509 | |||
510 | err = gpio_request(CORGI_GPIO_MAX1111_CS, "MAX1111_CS"); | ||
511 | if (err) | ||
512 | goto err_free_2; | ||
513 | |||
514 | gpio_direction_output(CORGI_GPIO_ADS7846_CS, 1); | ||
515 | gpio_direction_output(CORGI_GPIO_LCDCON_CS, 1); | ||
516 | gpio_direction_output(CORGI_GPIO_MAX1111_CS, 1); | ||
517 | |||
518 | pxa2xx_set_spi_info(1, &corgi_spi_info); | ||
519 | spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices)); | ||
520 | return; | ||
521 | |||
522 | err_free_2: | ||
523 | gpio_free(CORGI_GPIO_LCDCON_CS); | ||
524 | err_free_1: | ||
525 | gpio_free(CORGI_GPIO_ADS7846_CS); | ||
526 | } | ||
527 | #else | ||
528 | static inline void corgi_init_spi(void) {} | ||
529 | #endif | ||
558 | 530 | ||
559 | static struct platform_device *devices[] __initdata = { | 531 | static struct platform_device *devices[] __initdata = { |
560 | &corgiscoop_device, | 532 | &corgiscoop_device, |
561 | &corgissp_device, | ||
562 | &corgifb_device, | 533 | &corgifb_device, |
563 | &corgikbd_device, | 534 | &corgikbd_device, |
564 | &corgibl_device, | ||
565 | &corgits_device, | ||
566 | &corgiled_device, | 535 | &corgiled_device, |
567 | }; | 536 | }; |
568 | 537 | ||
@@ -592,7 +561,7 @@ static void __init corgi_init(void) | |||
592 | 561 | ||
593 | pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config)); | 562 | pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config)); |
594 | 563 | ||
595 | corgi_ssp_set_machinfo(&corgi_ssp_machinfo); | 564 | corgi_init_spi(); |
596 | 565 | ||
597 | pxa_set_udc_info(&udc_info); | 566 | pxa_set_udc_info(&udc_info); |
598 | pxa_set_mci_info(&corgi_mci_platform_data); | 567 | pxa_set_mci_info(&corgi_mci_platform_data); |