⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 system3.c

📁 优龙2410linux2.6.8内核源代码
💻 C
字号:
/* * linux/arch/arm/mach-sa1100/system3.c * * Copyright (C) 2001 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de> * * $Id: system3.c,v 1.1.6.1 2001/12/04 17:28:06 seletz Exp $ * * This file contains all PT Sytsem 3 tweaks. Based on original work from * Nicolas Pitre's assabet fixes * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * $Log: system3.c,v $ * Revision 1.1.6.1  2001/12/04 17:28:06  seletz * - merged from previous branch * * Revision 1.1.4.3  2001/12/04 15:16:31  seletz * - merged from linux_2_4_13_ac5_rmk2 * * Revision 1.1.4.2  2001/11/19 17:18:57  seletz * - more code cleanups * * Revision 1.1.4.1  2001/11/16 13:52:05  seletz * - PT Digital Board Support Code * * Revision 1.1.2.2  2001/11/05 16:46:18  seletz * - cleanups * * Revision 1.1.2.1  2001/10/15 16:00:43  seletz * - first revision working with new board * * */#include <linux/config.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/tty.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/cpufreq.h>#include <asm/hardware.h>#include <asm/mach-types.h>#include <asm/setup.h>#include <asm/irq.h>#include <asm/mach/arch.h>#include <asm/mach/map.h>#include <asm/mach/irq.h>#include <asm/mach/serial_sa1100.h>#include <linux/serial_core.h>#include "generic.h"#include <asm/hardware/sa1111.h>#define DEBUG 1#ifdef DEBUG#	define DPRINTK( x, args... )	printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args  );#else#	define DPRINTK( x, args... )	/* nix */#endif/********************************************************************** *  prototypes *//* init funcs */static int __init system3_init(void);static void __init system3_init_irq(void);static void __init system3_map_io(void);static u_int system3_get_mctrl(struct uart_port *port);static void system3_set_mctrl(struct uart_port *port, u_int mctrl);static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate);static int sdram_notifier(struct notifier_block *nb, unsigned long event, void *data);static void system3_lcd_power(int on);static void system3_backlight_power(int on);/********************************************************************** *  global data *//********************************************************************** *  static data */static struct map_desc system3_io_desc[] __initdata = { /* virtual     physical        length      type */  { 0xf3000000, PT_CPLD_BASE,   0x00100000, MT_DEVICE }, /* System Registers */  { 0xf4000000, PT_SA1111_BASE, 0x00100000, MT_DEVICE }  /* SA-1111 */};static struct sa1100_port_fns system3_port_fns __initdata = {	.set_mctrl	= system3_set_mctrl,	.get_mctrl	= system3_get_mctrl,	.pm		= system3_uart_pm,};static struct notifier_block system3_clkchg_block = {	.notifier_call	= sdram_notifier,};/********************************************************************** *  Static functions */static void __init system3_map_io(void){	DPRINTK( "%s\n", "START" );	sa1100_map_io();	iotable_init(system3_io_desc, ARRAY_SIZE(system3_io_desc));	sa1100_register_uart_fns(&system3_port_fns);	sa1100_register_uart(0, 1);	/* com port */	sa1100_register_uart(1, 2);	sa1100_register_uart(2, 3);	/* radio module */	Ser1SDCR0 |= SDCR0_SUS;}/********************************************************************* * Install IRQ handler */static voidsystem3_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs){	u_char irr;	//DPRINTK( "irq=%d, desc=%p, regs=%p\n", irq, desc, regs );	while (1) {		struct irqdesc *d;		/*		 * Acknowledge the parent IRQ.		 */		desc->chip->ack(irq);		/*		 * Read the interrupt reason register.  Let's have all		 * active IRQ bits high.  Note: there is a typo in the		 * Neponset user's guide for the SA1111 IRR level.		 */		//irr = PT_IRQSR & (PT_IRR_LAN | PT_IRR_SA1111);		irr = PT_IRQSR & (PT_IRR_SA1111);		/* SMC IRQ is low-active, so "switch" bit over */		//irr ^= (PT_IRR_LAN);		//DPRINTK( "irr=0x%02x\n", irr );		if ((irr & (PT_IRR_LAN | PT_IRR_SA1111)) == 0)			break;		/*		 * Since there is no individual mask, we have to		 * mask the parent IRQ.  This is safe, since we'll		 * recheck the register for any pending IRQs.		 */		if (irr & (PT_IRR_LAN)) {			desc->chip->mask(irq);			if (irr & PT_IRR_LAN) {				//DPRINTK( "SMC9196, irq=%d\n", IRQ_SYSTEM3_SMC9196 );				d = irq_desc + IRQ_SYSTEM3_SMC9196;				d->handle(IRQ_SYSTEM3_SMC9196, d, regs);			}#if 0 /* no SSP yet on system 4 */			if (irr & IRR_USAR) {				d = irq_desc + IRQ_NEPONSET_USAR;				d->handle(IRQ_NEPONSET_USAR, d, regs);			}#endif			desc->chip->unmask(irq);		}		if (irr & PT_IRR_SA1111) {			//DPRINTK( "SA1111, irq=%d\n", IRQ_SYSTEM3_SA1111 );			d = irq_desc + IRQ_SYSTEM3_SA1111;			d->handle(IRQ_SYSTEM3_SA1111, d, regs);		}	}}static void __init system3_init_irq(void){	/*	 * Install handler for GPIO25.	 */	set_irq_type(IRQ_GPIO25, IRQT_RISING);	set_irq_chained_handler(IRQ_GPIO25, system3_irq_handler);	/*	 * install eth irq	 */	set_irq_handler(IRQ_SYSTEM3_SMC9196, do_simple_IRQ);	set_irq_flags(IRQ_SYSTEM3_SMC9196, IRQF_VALID | IRQF_PROBE);}/********************************************************************** * On system 3 limit cpu frequency to 206 Mhz */static int sdram_notifier(struct notifier_block *nb, unsigned long event,		void *data){	struct cpufreq_policy *policy = data;	switch (event) {		case CPUFREQ_ADJUST:		case CPUFREQ_INCOMPATIBLE:			cpufreq_verify_within_limits(policy, 147500, 206000);			break;		case CPUFREQ_NOTIFY:			if ((policy->min < 147500) || 			    (policy->max > 206000))				panic("cpufreq failed to limit the speed\n");			break;	}	return 0;}/** *	system3_uart_pm - powermgmt callback function for system 3 UART *	@port: uart port structure *	@state: pm state *	@oldstate: old pm state * */static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate){	/* TODO: switch on/off uart in powersave mode */}/* * Note! this can be called from IRQ context. * FIXME: Handle PT Digital Board CTRL regs irq-safe. * * NB: system3 uses COM_RTS and COM_DTR for both UART1 (com port) * and UART3 (radio module).  We only handle them for UART1 here. */static void system3_set_mctrl(struct uart_port *port, u_int mctrl){	if (port->mapbase == _Ser1UTCR0) {		u_int set = 0, clear = 0;		if (mctrl & TIOCM_RTS)			set |= PT_CTRL2_RS1_RTS;		else			clear |= PT_CTRL2_RS1_RTS;		if (mctrl & TIOCM_DTR)			set |= PT_CTRL2_RS1_DTR;		else			clear |= PT_CTRL2_RS1_DTR;		PTCTRL2_clear(clear);		PTCTRL2_set(set);	}}static u_int system3_get_mctrl(struct uart_port *port){	u_int ret = 0;	u_int irqsr = PT_IRQSR;	/* need 2 reads to read current value */	irqsr = PT_IRQSR;	/* TODO: check IRQ source register for modem/com	 status lines and set them correctly. */	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;	return ret;}/** *	system3_lcd_backlight_on - switch system 3 lcd backlight on * */int system3_lcd_backlight_on( void ){	PTCTRL0_set( PT_CTRL0_LCD_BL );	return 0;}/** *	system3_lcd_backlight_off - switch system 3 lcd backlight off * */static void system3_lcd_backlight_off(void){	PTCTRL0_clear( PT_CTRL0_LCD_BL );}/** *	system3_lcd_on - switch system 3 lcd on * */static void system3_lcd_on(void){	DPRINTK( "%s\n", "START" );	PTCTRL0_set( PT_CTRL0_LCD_EN );	/* brightness / contrast */	sa1111_enable_device(SKPCR_PWMCLKEN);	PB_DDR = 0xFFFFFFFF;	SKPEN0 = 1;	SKPEN1 = 1;}/** *	system3_lcd_off - switch system 3 lcd off * */static void system3_lcd_off(void){	DPRINTK( "%s\n", "START" );	PTCTRL0_clear( PT_CTRL0_LCD_EN );	SKPEN0 = 0;	SKPEN1 = 0;	sa1111_disable_device(SKPCR_PWMCLKEN);}/** *	system3_lcd_contrast - set system 3 contrast *	@value:		the new contrast * */static void system3_lcd_contrast(unsigned char value){	DPRINTK( "value=0x%02x\n", value );	SYS3LCDCONTR = value;}/** *	system3_lcd_brightness - set system 3 brightness *	@value:		the new brightness * */static void system3_lcd_brightness(unsigned char value){	DPRINTK( "value=0x%02x\n", value );	SYS3LCDBRIGHT = value;}static void system3_lcd_power(int on){	if (on) {		system3_lcd_on();	} else {		system3_lcd_off();	}}static void system3_backlight_power(int on){	if (on) {		system3_lcd_backlight_on();		system3_lcd_contrast(0x95);		system3_lcd_brightness(240);	} else {		system3_lcd_backlight_off();	}}static struct resource sa1111_resources[] = {	[0] = {		.start		= PT_SA1111_BASE,		.end		= PT_SA1111_BASE + 0x00001fff,		.flags		= IORESOURCE_MEM,	},	[1] = {		.start		= IRQ_SYSTEM3_SA1111,		.end		= IRQ_SYSTEM3_SA1111,		.flags		= IORESOURCE_IRQ,	},};static u64 sa1111_dmamask = 0xffffffffUL;static struct platform_device sa1111_device = {	.name		= "sa1111",	.id		= 0,	.dev		= {		.dma_mask = &sa1111_dmamask,		.coherent_dma_mask = 0xffffffff,	},	.num_resources	= ARRAY_SIZE(sa1111_resources),	.resource	= sa1111_resources,};static struct platform_device *devices[] __initdata = {	&sa1111_device,};static int __init system3_init(void){	int ret = 0;	DPRINTK( "%s\n", "START" );	if ( !machine_is_pt_system3() ) {		ret = -EINVAL;		goto DONE;	}	sa1100fb_lcd_power = system3_lcd_power;	sa1100fb_backlight_power = system3_backlight_power;	/* init control register */	PT_CTRL0 = PT_CTRL0_INIT;	PT_CTRL1 = 0x02;	PT_CTRL2 = 0x00;	DPRINTK( "CTRL[0]=0x%02x\n", PT_CTRL0 );	DPRINTK( "CTRL[1]=0x%02x\n", PT_CTRL1 );	DPRINTK( "CTRL[2]=0x%02x\n", PT_CTRL2 );	/*	 * Ensure that the memory bus request/grant signals are setup,	 * and the grant is held in its inactive state.	 */	sa1110_mb_disable();	system3_init_irq();	/*	 * Probe for a SA1111.	 */	ret = platform_add_devices(devices, ARRAY_SIZE(devices));	if (ret < 0) {		printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );		goto DONE;	}#ifdef CONFIG_CPU_FREQ	ret = cpufreq_register_notifier(&system3_clkchg_block);	if ( ret != 0 ) {		printk( KERN_WARNING"PT Digital Board: could not register clock scale callback\n" );		goto DONE;	}#endif	ret = 0;DONE:	DPRINTK( "ret=%d\n", ret );	return ret;}/********************************************************************** *  Exported Functions *//********************************************************************** *  kernel magic macros */arch_initcall(system3_init);MACHINE_START(PT_SYSTEM3, "PT System 3")	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)	BOOT_PARAMS(0xc0000100)	MAPIO(system3_map_io)	INITIRQ(sa1100_init_irq)	INITTIME(sa1100_init_time)MACHINE_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -