aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-sa1100/h3600.c
diff options
context:
space:
mode:
authorDmitry Artamonow <mad_soft@inbox.ru>2009-02-20 04:16:01 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-21 11:39:07 -0500
commit7bc35b56f3e1548d039964d44e181c29398432b4 (patch)
tree242280ca10ebd33a7e2c3f874bfff6b4db036bf1 /arch/arm/mach-sa1100/h3600.c
parent1c7880dffceef58fad446e2157164ccb3d468159 (diff)
[ARM] 5407/1: SA1100: drop broken for ages iPAQ h3800 support
Code has never been in buildable state since initial merge. Signed-off-by: Dmitry Artamonow <mad_soft@inbox.ru> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-sa1100/h3600.c')
-rw-r--r--arch/arm/mach-sa1100/h3600.c392
1 files changed, 0 insertions, 392 deletions
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index af25a78d705..b9aaa45c6ca 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -42,14 +42,7 @@
42#include <asm/mach/serial_sa1100.h> 42#include <asm/mach/serial_sa1100.h>
43 43
44#include <mach/h3600.h> 44#include <mach/h3600.h>
45
46#if defined (CONFIG_SA1100_H3600) || defined (CONFIG_SA1100_H3100)
47#include <mach/h3600_gpio.h> 45#include <mach/h3600_gpio.h>
48#endif
49
50#ifdef CONFIG_SA1100_H3800
51#include <mach/h3600_asic.h>
52#endif
53 46
54#include "generic.h" 47#include "generic.h"
55 48
@@ -519,388 +512,3 @@ MACHINE_END
519 512
520#endif /* CONFIG_SA1100_H3600 */ 513#endif /* CONFIG_SA1100_H3600 */
521 514
522#ifdef CONFIG_SA1100_H3800
523
524#define SET_ASIC1(x) \
525 do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0)
526
527#define SET_ASIC2(x) \
528 do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0)
529
530#define CLEAR_ASIC1(x) \
531 do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0)
532
533#define CLEAR_ASIC2(x) \
534 do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0)
535
536
537/*
538 On screen enable, we get
539
540 h3800_video_power_on(1)
541 LCD controller starts
542 h3800_video_lcd_enable(1)
543
544 On screen disable, we get
545
546 h3800_video_lcd_enable(0)
547 LCD controller stops
548 h3800_video_power_on(0)
549*/
550
551
552static void h3800_video_power_on(int setp)
553{
554 if (setp) {
555 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_ON;
556 msleep(30);
557 H3800_ASIC1_GPIO_OUT |= GPIO1_VGL_ON;
558 msleep(5);
559 H3800_ASIC1_GPIO_OUT |= GPIO1_VGH_ON;
560 msleep(50);
561 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_5V_ON;
562 msleep(5);
563 } else {
564 msleep(5);
565 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_5V_ON;
566 msleep(50);
567 H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGL_ON;
568 msleep(5);
569 H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGH_ON;
570 msleep(100);
571 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_ON;
572 }
573}
574
575static void h3800_video_lcd_enable(int setp)
576{
577 if (setp) {
578 msleep(17); // Wait one from before turning on
579 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_PCI;
580 } else {
581 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_PCI;
582 msleep(30); // Wait before turning off
583 }
584}
585
586
587static void h3800_control_egpio(enum ipaq_egpio_type x, int setp)
588{
589 switch (x) {
590 case IPAQ_EGPIO_LCD_POWER:
591 h3800_video_power_on(setp);
592 break;
593 case IPAQ_EGPIO_LCD_ENABLE:
594 h3800_video_lcd_enable(setp);
595 break;
596 case IPAQ_EGPIO_CODEC_NRESET:
597 case IPAQ_EGPIO_AUDIO_ON:
598 case IPAQ_EGPIO_QMUTE:
599 printk("%s: error - should not be called\n", __func__);
600 break;
601 case IPAQ_EGPIO_OPT_NVRAM_ON:
602 SET_ASIC2(GPIO2_OPT_ON_NVRAM);
603 break;
604 case IPAQ_EGPIO_OPT_ON:
605 SET_ASIC2(GPIO2_OPT_ON);
606 break;
607 case IPAQ_EGPIO_CARD_RESET:
608 SET_ASIC2(GPIO2_OPT_PCM_RESET);
609 break;
610 case IPAQ_EGPIO_OPT_RESET:
611 SET_ASIC2(GPIO2_OPT_RESET);
612 break;
613 case IPAQ_EGPIO_IR_ON:
614 CLEAR_ASIC1(GPIO1_IR_ON_N);
615 break;
616 case IPAQ_EGPIO_IR_FSEL:
617 break;
618 case IPAQ_EGPIO_RS232_ON:
619 SET_ASIC1(GPIO1_RS232_ON);
620 break;
621 case IPAQ_EGPIO_VPP_ON:
622 H3800_ASIC2_FlashWP_VPP_ON = setp;
623 break;
624 }
625}
626
627static unsigned long h3800_read_egpio(void)
628{
629 return H3800_ASIC1_GPIO_OUT | (H3800_ASIC2_GPIOPIOD << 16);
630}
631
632/* We need to fix ASIC2 GPIO over suspend/resume. At the moment,
633 it doesn't appear that ASIC1 GPIO has the same problem */
634
635static int h3800_pm_callback(int req)
636{
637 static u16 asic1_data;
638 static u16 asic2_data;
639 int result = 0;
640
641 printk("%s %d\n", __func__, req);
642
643 switch (req) {
644 case PM_RESUME:
645 MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000; /* Set MSC2 correctly */
646
647 H3800_ASIC2_GPIOPIOD = asic2_data;
648 H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
649 | GPIO2_SD_DETECT
650 | GPIO2_EAR_IN_N
651 | GPIO2_USB_DETECT_N
652 | GPIO2_SD_CON_SLT;
653
654 H3800_ASIC1_GPIO_OUT = asic1_data;
655
656 if (ipaq_model_ops.pm_callback_aux)
657 result = ipaq_model_ops.pm_callback_aux(req);
658 break;
659
660 case PM_SUSPEND:
661 if (ipaq_model_ops.pm_callback_aux &&
662 ((result = ipaq_model_ops.pm_callback_aux(req)) != 0))
663 return result;
664
665 asic1_data = H3800_ASIC1_GPIO_OUT;
666 asic2_data = H3800_ASIC2_GPIOPIOD;
667 break;
668 default:
669 printk("%s: unrecognized PM callback\n", __func__);
670 break;
671 }
672 return result;
673}
674
675static struct ipaq_model_ops h3800_model_ops __initdata = {
676 .generic_name = "3800",
677 .control = h3800_control_egpio,
678 .read = h3800_read_egpio,
679 .pm_callback = h3800_pm_callback
680};
681
682#define MAX_ASIC_ISR_LOOPS 20
683
684/* The order of these is important - see #include <mach/irqs.h> */
685static u32 kpio_irq_mask[] = {
686 KPIO_KEY_ALL,
687 KPIO_SPI_INT,
688 KPIO_OWM_INT,
689 KPIO_ADC_INT,
690 KPIO_UART_0_INT,
691 KPIO_UART_1_INT,
692 KPIO_TIMER_0_INT,
693 KPIO_TIMER_1_INT,
694 KPIO_TIMER_2_INT
695};
696
697static u32 gpio_irq_mask[] = {
698 GPIO2_PEN_IRQ,
699 GPIO2_SD_DETECT,
700 GPIO2_EAR_IN_N,
701 GPIO2_USB_DETECT_N,
702 GPIO2_SD_CON_SLT,
703};
704
705static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc)
706{
707 int i;
708
709 if (0) printk("%s: interrupt received\n", __func__);
710
711 desc->chip->ack(irq);
712
713 for (i = 0; i < MAX_ASIC_ISR_LOOPS && (GPLR & GPIO_H3800_ASIC); i++) {
714 u32 irq;
715 int j;
716
717 /* KPIO */
718 irq = H3800_ASIC2_KPIINTFLAG;
719 if (0) printk("%s KPIO 0x%08X\n", __func__, irq);
720 for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++)
721 if (irq & kpio_irq_mask[j])
722 handle_edge_irq(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j);
723
724 /* GPIO2 */
725 irq = H3800_ASIC2_GPIINTFLAG;
726 if (0) printk("%s GPIO 0x%08X\n", __func__, irq);
727 for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++)
728 if (irq & gpio_irq_mask[j])
729 handle_edge_irq(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j);
730 }
731
732 if (i >= MAX_ASIC_ISR_LOOPS)
733 printk("%s: interrupt processing overrun\n", __func__);
734
735 /* For level-based interrupts */
736 desc->chip->unmask(irq);
737
738}
739
740static struct irqaction h3800_irq = {
741 .name = "h3800_asic",
742 .handler = h3800_IRQ_demux,
743 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
744};
745
746u32 kpio_int_shadow = 0;
747
748
749/* mask_ack <- IRQ is first serviced.
750 mask <- IRQ is disabled.
751 unmask <- IRQ is enabled
752
753 The INTCLR registers are poorly documented. I believe that writing
754 a "1" to the register clears the specific interrupt, but the documentation
755 indicates writing a "0" clears the interrupt. In any case, they shouldn't
756 be read (that's the INTFLAG register)
757 */
758
759static void h3800_mask_ack_kpio_irq(unsigned int irq)
760{
761 u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
762 kpio_int_shadow &= ~mask;
763 H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
764 H3800_ASIC2_KPIINTCLR = mask;
765}
766
767static void h3800_mask_kpio_irq(unsigned int irq)
768{
769 u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
770 kpio_int_shadow &= ~mask;
771 H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
772}
773
774static void h3800_unmask_kpio_irq(unsigned int irq)
775{
776 u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
777 kpio_int_shadow |= mask;
778 H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
779}
780
781static void h3800_mask_ack_gpio_irq(unsigned int irq)
782{
783 u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
784 H3800_ASIC2_GPIINTSTAT &= ~mask;
785 H3800_ASIC2_GPIINTCLR = mask;
786}
787
788static void h3800_mask_gpio_irq(unsigned int irq)
789{
790 u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
791 H3800_ASIC2_GPIINTSTAT &= ~mask;
792 }
793
794static void h3800_unmask_gpio_irq(unsigned int irq)
795{
796 u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
797 H3800_ASIC2_GPIINTSTAT |= mask;
798}
799
800static void __init h3800_init_irq(void)
801{
802 int i;
803
804 /* Initialize standard IRQs */
805 sa1100_init_irq();
806
807 /* Disable all IRQs and set up clock */
808 H3800_ASIC2_KPIINTSTAT = 0; /* Disable all interrupts */
809 H3800_ASIC2_GPIINTSTAT = 0;
810
811 H3800_ASIC2_KPIINTCLR = 0; /* Clear all KPIO interrupts */
812 H3800_ASIC2_GPIINTCLR = 0; /* Clear all GPIO interrupts */
813
814// H3800_ASIC2_KPIINTCLR = 0xffff; /* Clear all KPIO interrupts */
815// H3800_ASIC2_GPIINTCLR = 0xffff; /* Clear all GPIO interrupts */
816
817 H3800_ASIC2_CLOCK_Enable |= ASIC2_CLOCK_EX0; /* 32 kHZ crystal on */
818 H3800_ASIC2_INTR_ClockPrescale |= ASIC2_INTCPS_SET;
819 H3800_ASIC2_INTR_ClockPrescale = ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET;
820 H3800_ASIC2_INTR_TimerSet = 1;
821
822#if 0
823 for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) {
824 int irq = i + H3800_KPIO_IRQ_START;
825 irq_desc[irq].valid = 1;
826 irq_desc[irq].probe_ok = 1;
827 set_irq_chip(irq, &h3800_kpio_irqchip);
828 }
829
830 for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) {
831 int irq = i + H3800_GPIO_IRQ_START;
832 irq_desc[irq].valid = 1;
833 irq_desc[irq].probe_ok = 1;
834 set_irq_chip(irq, &h3800_gpio_irqchip);
835 }
836#endif
837 set_irq_type(IRQ_GPIO_H3800_ASIC, IRQ_TYPE_EDGE_RISING);
838 set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux);
839}
840
841
842#define ASIC1_OUTPUTS 0x7fff /* First 15 bits are used */
843
844static void __init h3800_map_io(void)
845{
846 h3xxx_map_io();
847
848 /* Add wakeup on AC plug/unplug */
849 PWER |= PWER_GPIO12;
850
851 /* Initialize h3800-specific values here */
852 GPCR = 0x0fffffff; /* All outputs are set low by default */
853 GAFR = GPIO_H3800_CLK_OUT |
854 GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
855 GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
856 GPDR = GPIO_H3800_CLK_OUT |
857 GPIO_H3600_COM_RTS | GPIO_H3600_L3_CLOCK |
858 GPIO_H3600_L3_MODE | GPIO_H3600_L3_DATA |
859 GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
860 GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
861 TUCR = TUCR_3_6864MHz; /* Seems to be used only for the Bluetooth UART */
862
863 /* Fix the memory bus */
864 MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;
865
866 /* Set up ASIC #1 */
867 H3800_ASIC1_GPIO_DIR = ASIC1_OUTPUTS; /* All outputs */
868 H3800_ASIC1_GPIO_MASK = ASIC1_OUTPUTS; /* No interrupts */
869 H3800_ASIC1_GPIO_SLEEP_MASK = ASIC1_OUTPUTS;
870 H3800_ASIC1_GPIO_SLEEP_DIR = ASIC1_OUTPUTS;
871 H3800_ASIC1_GPIO_SLEEP_OUT = GPIO1_EAR_ON_N;
872 H3800_ASIC1_GPIO_BATT_FAULT_DIR = ASIC1_OUTPUTS;
873 H3800_ASIC1_GPIO_BATT_FAULT_OUT = GPIO1_EAR_ON_N;
874
875 H3800_ASIC1_GPIO_OUT = GPIO1_IR_ON_N
876 | GPIO1_RS232_ON
877 | GPIO1_EAR_ON_N;
878
879 /* Set up ASIC #2 */
880 H3800_ASIC2_GPIOPIOD = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
881 H3800_ASIC2_GPOBFSTAT = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
882
883 H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
884 | GPIO2_SD_DETECT
885 | GPIO2_EAR_IN_N
886 | GPIO2_USB_DETECT_N
887 | GPIO2_SD_CON_SLT;
888
889 /* TODO : Set sleep states & battery fault states */
890
891 /* Clear VPP Enable */
892 H3800_ASIC2_FlashWP_VPP_ON = 0;
893 ipaq_model_ops = h3800_model_ops;
894}
895
896MACHINE_START(H3800, "Compaq iPAQ H3800")
897 .phys_io = 0x80000000,
898 .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
899 .boot_params = 0xc0000100,
900 .map_io = h3800_map_io,
901 .init_irq = h3800_init_irq,
902 .timer = &sa1100_timer,
903 .init_machine = h3xxx_mach_init,
904MACHINE_END
905
906#endif /* CONFIG_SA1100_H3800 */