aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Miao <eric.miao@marvell.com>2008-08-28 20:09:48 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-09-23 17:04:36 -0400
commitedb403fbfb0ad56e62d8ebbecc3b846487020e0f (patch)
treef0b10d6738aef50ad886e09d6735b1398875c989
parent9ae808d8b1d8a99832798a6699b4cb7f51bfc872 (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>
-rw-r--r--arch/arm/mach-pxa/Makefile2
-rw-r--r--arch/arm/mach-pxa/corgi.c293
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
28obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 28obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
29obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o 29obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
30obj-$(CONFIG_MACH_COLIBRI) += colibri.o 30obj-$(CONFIG_MACH_COLIBRI) += colibri.o
31obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o 31obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o sharpsl_pm.o corgi_pm.o
32obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o 32obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
33obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o 33obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
34obj-$(CONFIG_MACH_POODLE) += poodle.o 34obj-$(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
152EXPORT_SYMBOL(corgiscoop_device); 156EXPORT_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 */
162struct platform_device corgissp_device = {
163 .name = "corgi-ssp",
164 .dev = {
165 .parent = &corgiscoop_device.dev,
166 },
167 .id = -1,
168};
169
170struct 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 */
184static void w100_lcdtg_suspend(struct w100fb_par *par)
185{
186 corgi_lcdtg_suspend();
187}
188
189static void w100_lcdtg_init(struct w100fb_par *par)
190{
191 corgi_lcdtg_hw_init(par->xres);
192}
193
194
195static struct w100_tg_info corgi_lcdtg_info = {
196 .change = w100_lcdtg_init,
197 .suspend = w100_lcdtg_suspend,
198 .resume = w100_lcdtg_init,
199};
200
201static struct w100_mem_info corgi_fb_mem = { 158static 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
278static struct w100fb_mach_info corgi_fb_info = { 235static 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 */
314static 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
325static 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
340static 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
349static 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 */
380static unsigned long (*get_hsync_invperiod)(struct device *dev);
381
382static 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
388static 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
398static void corgi_put_hsync(void)
399{
400 if (get_hsync_invperiod)
401 symbol_put(w100fb_get_hsynclen);
402 get_hsync_invperiod = NULL;
403}
404
405static void corgi_wait_hsync(void)
406{
407 sharpsl_wait_sync(CORGI_GPIO_HSYNC);
408}
409
410static 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
418static 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
424static 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)
405static struct pxa2xx_spi_master corgi_spi_info = {
406 .num_chipselect = 3,
407};
408
409static 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
417static void corgi_ads7846_cs(u32 command)
418{
419 gpio_set_value(CORGI_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT));
420}
421
422static struct pxa2xx_spi_chip corgi_ads7846_chip = {
423 .cs_control = corgi_ads7846_cs,
424};
425
426static 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
435static 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
446static 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
455static void corgi_lcdcon_cs(u32 command)
456{
457 gpio_set_value(CORGI_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT));
458}
459
460static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
461 .cs_control = corgi_lcdcon_cs,
462};
463
464static void corgi_max1111_cs(u32 command)
465{
466 gpio_set_value(CORGI_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT));
467}
468
469static struct pxa2xx_spi_chip corgi_max1111_chip = {
470 .cs_control = corgi_max1111_cs,
471};
472
473static 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
498static 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
522err_free_2:
523 gpio_free(CORGI_GPIO_LCDCON_CS);
524err_free_1:
525 gpio_free(CORGI_GPIO_ADS7846_CS);
526}
527#else
528static inline void corgi_init_spi(void) {}
529#endif
558 530
559static struct platform_device *devices[] __initdata = { 531static 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);