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

📄 locomo.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * linux/arch/arm/common/locomo.c * * Sharp LoCoMo support * * 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. * * This file contains all generic LoCoMo support. * * All initialization functions provided here are intended to be called * from machine specific code with proper arguments when required. * * Based on sa1111.c */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/platform_device.h>#include <linux/slab.h>#include <linux/spinlock.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/mach/irq.h>#include <asm/hardware/locomo.h>/* M62332 output channel selection */#define M62332_EVR_CH	1	/* M62332 volume channel number  */				/*   0 : CH.1 , 1 : CH. 2        *//* DAC send data */#define	M62332_SLAVE_ADDR	0x4e	/* Slave address  */#define	M62332_W_BIT		0x00	/* W bit (0 only) */#define	M62332_SUB_ADDR		0x00	/* Sub address    */#define	M62332_A_BIT		0x00	/* A bit (0 only) *//* DAC setup and hold times (expressed in us) */#define DAC_BUS_FREE_TIME	5	/*   4.7 us */#define DAC_START_SETUP_TIME	5	/*   4.7 us */#define DAC_STOP_SETUP_TIME	4	/*   4.0 us */#define DAC_START_HOLD_TIME	5	/*   4.7 us */#define DAC_SCL_LOW_HOLD_TIME	5	/*   4.7 us */#define DAC_SCL_HIGH_HOLD_TIME	4	/*   4.0 us */#define DAC_DATA_SETUP_TIME	1	/*   250 ns */#define DAC_DATA_HOLD_TIME	1	/*   300 ns */#define DAC_LOW_SETUP_TIME	1	/*   300 ns */#define DAC_HIGH_SETUP_TIME	1	/*  1000 ns *//* the following is the overall data for the locomo chip */struct locomo {	struct device *dev;	unsigned long phys;	unsigned int irq;	spinlock_t lock;	void __iomem *base;};struct locomo_dev_info {	unsigned long	offset;	unsigned long	length;	unsigned int	devid;	unsigned int	irq[1];	const char *	name;};/* All the locomo devices.  If offset is non-zero, the mapbase for the * locomo_dev will be set to the chip base plus offset.  If offset is * zero, then the mapbase for the locomo_dev will be set to zero.  An * offset of zero means the device only uses GPIOs or other helper * functions inside this file */static struct locomo_dev_info locomo_devices[] = {	{		.devid 		= LOCOMO_DEVID_KEYBOARD,		.irq = {			IRQ_LOCOMO_KEY,		},		.name		= "locomo-keyboard",		.offset		= LOCOMO_KEYBOARD,		.length		= 16,	},	{		.devid		= LOCOMO_DEVID_FRONTLIGHT,		.irq		= {},		.name		= "locomo-frontlight",		.offset		= LOCOMO_FRONTLIGHT,		.length		= 8,	},	{		.devid		= LOCOMO_DEVID_BACKLIGHT,		.irq		= {},		.name		= "locomo-backlight",		.offset		= LOCOMO_BACKLIGHT,		.length		= 8,	},	{		.devid		= LOCOMO_DEVID_AUDIO,		.irq		= {},		.name		= "locomo-audio",		.offset		= LOCOMO_AUDIO,		.length		= 4,	},	{		.devid		= LOCOMO_DEVID_LED,		.irq 		= {},		.name		= "locomo-led",		.offset		= LOCOMO_LED,		.length		= 8,	},	{		.devid		= LOCOMO_DEVID_UART,		.irq		= {},		.name		= "locomo-uart",		.offset		= 0,		.length		= 0,	},};/** LoCoMo interrupt handling stuff. * NOTE: LoCoMo has a 1 to many mapping on all of its IRQs. * that is, there is only one real hardware interrupt * we determine which interrupt it is by reading some IO memory. * We have two levels of expansion, first in the handler for the * hardware interrupt we generate an interrupt * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts * * hardware irq reads LOCOMO_ICR & 0x0f00 *   IRQ_LOCOMO_KEY_BASE *   IRQ_LOCOMO_GPIO_BASE *   IRQ_LOCOMO_LT_BASE *   IRQ_LOCOMO_SPI_BASE * IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001 *   IRQ_LOCOMO_KEY * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff *   IRQ_LOCOMO_GPIO[0-15] * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001 *   IRQ_LOCOMO_LT * IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F *   IRQ_LOCOMO_SPI_RFR *   IRQ_LOCOMO_SPI_RFW *   IRQ_LOCOMO_SPI_OVRN *   IRQ_LOCOMO_SPI_TEND */#define LOCOMO_IRQ_START	(IRQ_LOCOMO_KEY_BASE)#define LOCOMO_IRQ_KEY_START	(IRQ_LOCOMO_KEY)#define	LOCOMO_IRQ_GPIO_START	(IRQ_LOCOMO_GPIO0)#define	LOCOMO_IRQ_LT_START	(IRQ_LOCOMO_LT)#define	LOCOMO_IRQ_SPI_START	(IRQ_LOCOMO_SPI_RFR)static void locomo_handler(unsigned int irq, struct irqdesc *desc,			struct pt_regs *regs){	int req, i;	struct irqdesc *d;	void __iomem *mapbase = get_irq_chipdata(irq);	/* Acknowledge the parent IRQ */	desc->chip->ack(irq);	/* check why this interrupt was generated */	req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00;	if (req) {		/* generate the next interrupt(s) */		irq = LOCOMO_IRQ_START;		d = irq_desc + irq;		for (i = 0; i <= 3; i++, d++, irq++) {			if (req & (0x0100 << i)) {				desc_handle_irq(irq, d, regs);			}		}	}}static void locomo_ack_irq(unsigned int irq){}static void locomo_mask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_ICR);	r &= ~(0x0010 << (irq - LOCOMO_IRQ_START));	locomo_writel(r, mapbase + LOCOMO_ICR);}static void locomo_unmask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_ICR);	r |= (0x0010 << (irq - LOCOMO_IRQ_START));	locomo_writel(r, mapbase + LOCOMO_ICR);}static struct irqchip locomo_chip = {	.ack	= locomo_ack_irq,	.mask	= locomo_mask_irq,	.unmask	= locomo_unmask_irq,};static void locomo_key_handler(unsigned int irq, struct irqdesc *desc,			    struct pt_regs *regs){	struct irqdesc *d;	void __iomem *mapbase = get_irq_chipdata(irq);	if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {		d = irq_desc + LOCOMO_IRQ_KEY_START;		desc_handle_irq(LOCOMO_IRQ_KEY_START, d, regs);	}}static void locomo_key_ack_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);	r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START));	locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);}static void locomo_key_mask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);	r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START));	locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);}static void locomo_key_unmask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);	r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START));	locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);}static struct irqchip locomo_key_chip = {	.ack	= locomo_key_ack_irq,	.mask	= locomo_key_mask_irq,	.unmask	= locomo_key_unmask_irq,};static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc,			     struct pt_regs *regs){	int req, i;	struct irqdesc *d;	void __iomem *mapbase = get_irq_chipdata(irq);	req = 	locomo_readl(mapbase + LOCOMO_GIR) &		locomo_readl(mapbase + LOCOMO_GPD) &		0xffff;	if (req) {		irq = LOCOMO_IRQ_GPIO_START;		d = irq_desc + LOCOMO_IRQ_GPIO_START;		for (i = 0; i <= 15; i++, irq++, d++) {			if (req & (0x0001 << i)) {				desc_handle_irq(irq, d, regs);			}		}	}}static void locomo_gpio_ack_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_GWE);	r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GWE);	r = locomo_readl(mapbase + LOCOMO_GIS);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GIS);	r = locomo_readl(mapbase + LOCOMO_GWE);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GWE);}static void locomo_gpio_mask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_GIE);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GIE);}static void locomo_gpio_unmask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_GIE);	r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GIE);}static struct irqchip locomo_gpio_chip = {	.ack	= locomo_gpio_ack_irq,	.mask	= locomo_gpio_mask_irq,	.unmask	= locomo_gpio_unmask_irq,};static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc,			   struct pt_regs *regs){	struct irqdesc *d;	void __iomem *mapbase = get_irq_chipdata(irq);	if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {		d = irq_desc + LOCOMO_IRQ_LT_START;		desc_handle_irq(LOCOMO_IRQ_LT_START, d, regs);	}}static void locomo_lt_ack_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_LTINT);	r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START));	locomo_writel(r, mapbase + LOCOMO_LTINT);}static void locomo_lt_mask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_LTINT);	r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START));	locomo_writel(r, mapbase + LOCOMO_LTINT);}static void locomo_lt_unmask_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_LTINT);	r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START));	locomo_writel(r, mapbase + LOCOMO_LTINT);}static struct irqchip locomo_lt_chip = {	.ack	= locomo_lt_ack_irq,	.mask	= locomo_lt_mask_irq,	.unmask	= locomo_lt_unmask_irq,};static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,			    struct pt_regs *regs){	int req, i;	struct irqdesc *d;	void __iomem *mapbase = get_irq_chipdata(irq);	req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F;	if (req) {		irq = LOCOMO_IRQ_SPI_START;		d = irq_desc + irq;		for (i = 0; i <= 3; i++, irq++, d++) {			if (req & (0x0001 << i)) {				desc_handle_irq(irq, d, regs);			}		}	}}static void locomo_spi_ack_irq(unsigned int irq){	void __iomem *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_SPIWE);

⌨️ 快捷键说明

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