Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7bc35b56 authored by Dmitry Artamonow's avatar Dmitry Artamonow Committed by Russell King
Browse files

[ARM] 5407/1: SA1100: drop broken for ages iPAQ h3800 support



Code has never been in buildable state since initial
merge.

Signed-off-by: default avatarDmitry Artamonow <mad_soft@inbox.ru>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 1c7880df
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1093,7 +1093,7 @@ source "drivers/cpufreq/Kconfig"

config CPU_FREQ_SA1100
	bool
	depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
	depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
	default y

config CPU_FREQ_SA1110
+1 −11
Original line number Diff line number Diff line
@@ -71,19 +71,9 @@ config SA1100_H3600
	  <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
	  <http://www.compaq.com/products/handhelds/pocketpc/>

config SA1100_H3800
	bool "Compaq iPAQ H3800"
	help
	  Say Y here if you intend to run this kernel on the Compaq iPAQ H3800
	  series handheld computer.  Information about this machine and the
	  Linux port to this machine can be found at:

	  <http://www.handhelds.org/Compaq/index.html#iPAQ_H3800>
	  <http://www.compaq.com/products/handhelds/pocketpc/>

config SA1100_H3XXX
	bool
	depends on SA1100_H3100 || SA1100_H3600 || SA1100_H3800
	depends on SA1100_H3100 || SA1100_H3600
	default y

config SA1100_BADGE4
+0 −392
Original line number Diff line number Diff line
@@ -42,14 +42,7 @@
#include <asm/mach/serial_sa1100.h>

#include <mach/h3600.h>

#if defined (CONFIG_SA1100_H3600) || defined (CONFIG_SA1100_H3100)
#include <mach/h3600_gpio.h>
#endif

#ifdef CONFIG_SA1100_H3800
#include <mach/h3600_asic.h>
#endif

#include "generic.h"

@@ -519,388 +512,3 @@ MACHINE_END

#endif /* CONFIG_SA1100_H3600 */
#ifdef CONFIG_SA1100_H3800

#define SET_ASIC1(x) \
   do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0)

#define SET_ASIC2(x) \
   do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0)

#define CLEAR_ASIC1(x) \
   do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0)

#define CLEAR_ASIC2(x) \
   do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0)


/*
  On screen enable, we get

     h3800_video_power_on(1)
     LCD controller starts
     h3800_video_lcd_enable(1)

  On screen disable, we get

     h3800_video_lcd_enable(0)
     LCD controller stops
     h3800_video_power_on(0)
*/


static void h3800_video_power_on(int setp)
{
	if (setp) {
		H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_ON;
		msleep(30);
		H3800_ASIC1_GPIO_OUT |= GPIO1_VGL_ON;
		msleep(5);
		H3800_ASIC1_GPIO_OUT |= GPIO1_VGH_ON;
		msleep(50);
		H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_5V_ON;
		msleep(5);
	} else {
		msleep(5);
		H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_5V_ON;
		msleep(50);
		H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGL_ON;
		msleep(5);
		H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGH_ON;
		msleep(100);
		H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_ON;
	}
}

static void h3800_video_lcd_enable(int setp)
{
	if (setp) {
		msleep(17);	// Wait one from before turning on
		H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_PCI;
	} else {
		H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_PCI;
		msleep(30);	// Wait before turning off
	}
}


static void h3800_control_egpio(enum ipaq_egpio_type x, int setp)
{
	switch (x) {
	case IPAQ_EGPIO_LCD_POWER:
		h3800_video_power_on(setp);
		break;
	case IPAQ_EGPIO_LCD_ENABLE:
		h3800_video_lcd_enable(setp);
		break;
	case IPAQ_EGPIO_CODEC_NRESET:
	case IPAQ_EGPIO_AUDIO_ON:
	case IPAQ_EGPIO_QMUTE:
		printk("%s: error - should not be called\n", __func__);
		break;
	case IPAQ_EGPIO_OPT_NVRAM_ON:
		SET_ASIC2(GPIO2_OPT_ON_NVRAM);
		break;
	case IPAQ_EGPIO_OPT_ON:
		SET_ASIC2(GPIO2_OPT_ON);
		break;
	case IPAQ_EGPIO_CARD_RESET:
		SET_ASIC2(GPIO2_OPT_PCM_RESET);
		break;
	case IPAQ_EGPIO_OPT_RESET:
		SET_ASIC2(GPIO2_OPT_RESET);
		break;
	case IPAQ_EGPIO_IR_ON:
		CLEAR_ASIC1(GPIO1_IR_ON_N);
		break;
	case IPAQ_EGPIO_IR_FSEL:
		break;
	case IPAQ_EGPIO_RS232_ON:
		SET_ASIC1(GPIO1_RS232_ON);
		break;
	case IPAQ_EGPIO_VPP_ON:
		H3800_ASIC2_FlashWP_VPP_ON = setp;
		break;
	}
}

static unsigned long h3800_read_egpio(void)
{
	return H3800_ASIC1_GPIO_OUT | (H3800_ASIC2_GPIOPIOD << 16);
}

/* We need to fix ASIC2 GPIO over suspend/resume.  At the moment,
   it doesn't appear that ASIC1 GPIO has the same problem */

static int h3800_pm_callback(int req)
{
	static u16 asic1_data;
	static u16 asic2_data;
	int result = 0;

	printk("%s %d\n", __func__, req);

	switch (req) {
	case PM_RESUME:
		MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;  /* Set MSC2 correctly */

		H3800_ASIC2_GPIOPIOD = asic2_data;
		H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
			| GPIO2_SD_DETECT
			| GPIO2_EAR_IN_N
			| GPIO2_USB_DETECT_N
			| GPIO2_SD_CON_SLT;

		H3800_ASIC1_GPIO_OUT = asic1_data;

		if (ipaq_model_ops.pm_callback_aux)
			result = ipaq_model_ops.pm_callback_aux(req);
		break;

	case PM_SUSPEND:
		if (ipaq_model_ops.pm_callback_aux &&
		     ((result = ipaq_model_ops.pm_callback_aux(req)) != 0))
			return result;

		asic1_data = H3800_ASIC1_GPIO_OUT;
		asic2_data = H3800_ASIC2_GPIOPIOD;
		break;
	default:
		printk("%s: unrecognized PM callback\n", __func__);
		break;
	}
	return result;
}

static struct ipaq_model_ops h3800_model_ops __initdata = {
	.generic_name	= "3800",
	.control	= h3800_control_egpio,
	.read		= h3800_read_egpio,
	.pm_callback	= h3800_pm_callback
};

#define MAX_ASIC_ISR_LOOPS    20

/* The order of these is important - see #include <mach/irqs.h> */
static u32 kpio_irq_mask[] = {
	KPIO_KEY_ALL,
	KPIO_SPI_INT,
	KPIO_OWM_INT,
	KPIO_ADC_INT,
	KPIO_UART_0_INT,
	KPIO_UART_1_INT,
	KPIO_TIMER_0_INT,
	KPIO_TIMER_1_INT,
	KPIO_TIMER_2_INT
};

static u32 gpio_irq_mask[] = {
	GPIO2_PEN_IRQ,
	GPIO2_SD_DETECT,
	GPIO2_EAR_IN_N,
	GPIO2_USB_DETECT_N,
	GPIO2_SD_CON_SLT,
};

static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc)
{
	int i;

	if (0) printk("%s: interrupt received\n", __func__);

	desc->chip->ack(irq);

	for (i = 0; i < MAX_ASIC_ISR_LOOPS && (GPLR & GPIO_H3800_ASIC); i++) {
		u32 irq;
		int j;

		/* KPIO */
		irq = H3800_ASIC2_KPIINTFLAG;
		if (0) printk("%s KPIO 0x%08X\n", __func__, irq);
		for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++)
			if (irq & kpio_irq_mask[j])
				handle_edge_irq(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j);

		/* GPIO2 */
		irq = H3800_ASIC2_GPIINTFLAG;
		if (0) printk("%s GPIO 0x%08X\n", __func__, irq);
		for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++)
			if (irq & gpio_irq_mask[j])
				handle_edge_irq(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j);
	}

	if (i >= MAX_ASIC_ISR_LOOPS)
		printk("%s: interrupt processing overrun\n", __func__);

	/* For level-based interrupts */
	desc->chip->unmask(irq);

}

static struct irqaction h3800_irq = {
	.name		= "h3800_asic",
	.handler	= h3800_IRQ_demux,
	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};

u32 kpio_int_shadow = 0;


/* mask_ack <- IRQ is first serviced.
       mask <- IRQ is disabled.
     unmask <- IRQ is enabled

     The INTCLR registers are poorly documented.  I believe that writing
     a "1" to the register clears the specific interrupt, but the documentation
     indicates writing a "0" clears the interrupt.  In any case, they shouldn't
     be read (that's the INTFLAG register)
 */

static void h3800_mask_ack_kpio_irq(unsigned int irq)
{
	u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
	kpio_int_shadow &= ~mask;
	H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
	H3800_ASIC2_KPIINTCLR  = mask;
}

static void h3800_mask_kpio_irq(unsigned int irq)
{
	u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
	kpio_int_shadow &= ~mask;
	H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
}

static void h3800_unmask_kpio_irq(unsigned int irq)
{
	u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
	kpio_int_shadow |= mask;
	H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
}

static void h3800_mask_ack_gpio_irq(unsigned int irq)
{
	u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
	H3800_ASIC2_GPIINTSTAT &= ~mask;
	H3800_ASIC2_GPIINTCLR	= mask;
}

static void h3800_mask_gpio_irq(unsigned int irq)
{
	u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
	H3800_ASIC2_GPIINTSTAT &= ~mask;
	}

static void h3800_unmask_gpio_irq(unsigned int irq)
{
	u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
	H3800_ASIC2_GPIINTSTAT |= mask;
}

static void __init h3800_init_irq(void)
{
	int i;

	/* Initialize standard IRQs */
	sa1100_init_irq();

	/* Disable all IRQs and set up clock */
	H3800_ASIC2_KPIINTSTAT	   =  0;     /* Disable all interrupts */
	H3800_ASIC2_GPIINTSTAT	   =  0;

	H3800_ASIC2_KPIINTCLR	   =  0;     /* Clear all KPIO interrupts */
	H3800_ASIC2_GPIINTCLR	   =  0;     /* Clear all GPIO interrupts */

//	H3800_ASIC2_KPIINTCLR	   =  0xffff;	  /* Clear all KPIO interrupts */
//	H3800_ASIC2_GPIINTCLR	   =  0xffff;	  /* Clear all GPIO interrupts */

	H3800_ASIC2_CLOCK_Enable       |= ASIC2_CLOCK_EX0;   /* 32 kHZ crystal on */
	H3800_ASIC2_INTR_ClockPrescale |= ASIC2_INTCPS_SET;
	H3800_ASIC2_INTR_ClockPrescale	= ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET;
	H3800_ASIC2_INTR_TimerSet	= 1;

#if 0
	for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) {
		int irq = i + H3800_KPIO_IRQ_START;
		irq_desc[irq].valid    = 1;
		irq_desc[irq].probe_ok = 1;
		set_irq_chip(irq, &h3800_kpio_irqchip);
	}

	for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) {
		int irq = i + H3800_GPIO_IRQ_START;
		irq_desc[irq].valid    = 1;
		irq_desc[irq].probe_ok = 1;
		set_irq_chip(irq, &h3800_gpio_irqchip);
	}
#endif
	set_irq_type(IRQ_GPIO_H3800_ASIC, IRQ_TYPE_EDGE_RISING);
	set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux);
}


#define ASIC1_OUTPUTS	 0x7fff   /* First 15 bits are used */

static void __init h3800_map_io(void)
{
	h3xxx_map_io();

	/* Add wakeup on AC plug/unplug */
	PWER  |= PWER_GPIO12;

	/* Initialize h3800-specific values here */
	GPCR = 0x0fffffff;	 /* All outputs are set low by default */
	GAFR =	GPIO_H3800_CLK_OUT |
		GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
		GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
	GPDR =	GPIO_H3800_CLK_OUT |
		GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
		GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
		GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
		GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
	TUCR =	TUCR_3_6864MHz;   /* Seems to be used only for the Bluetooth UART */

	/* Fix the memory bus */
	MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;

	/* Set up ASIC #1 */
	H3800_ASIC1_GPIO_DIR		= ASIC1_OUTPUTS;	    /* All outputs */
	H3800_ASIC1_GPIO_MASK		= ASIC1_OUTPUTS;	    /* No interrupts */
	H3800_ASIC1_GPIO_SLEEP_MASK	= ASIC1_OUTPUTS;
	H3800_ASIC1_GPIO_SLEEP_DIR	= ASIC1_OUTPUTS;
	H3800_ASIC1_GPIO_SLEEP_OUT	= GPIO1_EAR_ON_N;
	H3800_ASIC1_GPIO_BATT_FAULT_DIR = ASIC1_OUTPUTS;
	H3800_ASIC1_GPIO_BATT_FAULT_OUT = GPIO1_EAR_ON_N;

	H3800_ASIC1_GPIO_OUT = GPIO1_IR_ON_N
				      | GPIO1_RS232_ON
				      | GPIO1_EAR_ON_N;

	/* Set up ASIC #2 */
	H3800_ASIC2_GPIOPIOD	= GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
	H3800_ASIC2_GPOBFSTAT	= GPIO2_IN_Y1_N | GPIO2_IN_X1_N;

	H3800_ASIC2_GPIODIR	= GPIO2_PEN_IRQ
				      | GPIO2_SD_DETECT
				      | GPIO2_EAR_IN_N
				      | GPIO2_USB_DETECT_N
				      | GPIO2_SD_CON_SLT;

	/* TODO : Set sleep states & battery fault states */

	/* Clear VPP Enable */
	H3800_ASIC2_FlashWP_VPP_ON = 0;
	ipaq_model_ops = h3800_model_ops;
}

MACHINE_START(H3800, "Compaq iPAQ H3800")
	.phys_io	= 0x80000000,
	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
	.boot_params	= 0xc0000100,
	.map_io		= h3800_map_io,
	.init_irq	= h3800_init_irq,
	.timer		= &sa1100_timer,
	.init_machine	= h3xxx_mach_init,
MACHINE_END

#endif /* CONFIG_SA1100_H3800 */
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ typedef int __bitwise pm_request_t;
#define PM_RESUME	((__force pm_request_t) 2)	/* enter D0 */

/* generalized support for H3xxx series Compaq Pocket PC's */
#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600() || machine_is_h3800())
#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600())

/* Physical memory regions corresponding to chip selects */
#define H3600_EGPIO_PHYS	(SA1100_CS5_PHYS + 0x01000000)
+0 −463

File changed.

Preview size limit exceeded, changes collapsed.

Loading