diff options
| -rw-r--r-- | arch/arm/common/locomo.c | 359 | ||||
| -rw-r--r-- | include/asm-arm/hardware/locomo.h | 224 |
2 files changed, 443 insertions, 140 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 34c8cf33ad9a..41f12658c8b4 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -34,11 +34,33 @@ #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 *base; }; @@ -50,7 +72,57 @@ struct locomo_dev_info { 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, + }, }; @@ -146,7 +218,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc, struct irqdesc *d; void *mapbase = get_irq_chipdata(irq); - if (locomo_readl(mapbase + LOCOMO_KIC) & 0x0001) { + if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { d = irq_desc + LOCOMO_IRQ_KEY_START; d->handle(LOCOMO_IRQ_KEY_START, d, regs); } @@ -156,27 +228,27 @@ static void locomo_key_ack_irq(unsigned int irq) { void *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_KIC); + r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START)); - locomo_writel(r, mapbase + LOCOMO_KIC); + locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); } static void locomo_key_mask_irq(unsigned int irq) { void *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_KIC); + r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START)); - locomo_writel(r, mapbase + LOCOMO_KIC); + locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); } static void locomo_key_unmask_irq(unsigned int irq) { void *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_KIC); + r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START)); - locomo_writel(r, mapbase + LOCOMO_KIC); + locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); } static struct irqchip locomo_key_chip = { @@ -421,13 +493,11 @@ static void locomo_dev_release(struct device *_dev) { struct locomo_dev *dev = LOCOMO_DEV(_dev); - release_resource(&dev->res); kfree(dev); } static int -locomo_init_one_child(struct locomo *lchip, struct resource *parent, - struct locomo_dev_info *info) +locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info) { struct locomo_dev *dev; int ret; @@ -454,25 +524,17 @@ locomo_init_one_child(struct locomo *lchip, struct resource *parent, dev->dev.bus = &locomo_bus_type; dev->dev.release = locomo_dev_release; dev->dev.coherent_dma_mask = lchip->dev->coherent_dma_mask; - dev->res.start = lchip->phys + info->offset; - dev->res.end = dev->res.start + info->length; - dev->res.name = dev->dev.bus_id; - dev->res.flags = IORESOURCE_MEM; - dev->mapbase = lchip->base + info->offset; - memmove(dev->irq, info->irq, sizeof(dev->irq)); - if (info->length) { - ret = request_resource(parent, &dev->res); - if (ret) { - printk("LoCoMo: failed to allocate resource for %s\n", - dev->res.name); - goto out; - } - } + if (info->offset) + dev->mapbase = lchip->base + info->offset; + else + dev->mapbase = 0; + dev->length = info->length; + + memmove(dev->irq, info->irq, sizeof(dev->irq)); ret = device_register(&dev->dev); if (ret) { - release_resource(&dev->res); out: kfree(dev); } @@ -504,6 +566,8 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) memset(lchip, 0, sizeof(struct locomo)); + spin_lock_init(&lchip->lock); + lchip->dev = me; dev_set_drvdata(lchip->dev, lchip); @@ -523,7 +587,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) /* locomo initialize */ locomo_writel(0, lchip->base + LOCOMO_ICR); /* KEYBOARD */ - locomo_writel(0, lchip->base + LOCOMO_KIC); + locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC); /* GPIO */ locomo_writel(0, lchip->base + LOCOMO_GPO); @@ -534,8 +598,8 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) locomo_writel(0, lchip->base + LOCOMO_GIE); /* FrontLight */ - locomo_writel(0, lchip->base + LOCOMO_ALS); - locomo_writel(0, lchip->base + LOCOMO_ALD); + locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); + locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); /* Longtime timer */ locomo_writel(0, lchip->base + LOCOMO_LTINT); /* SPI */ @@ -578,7 +642,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) locomo_setup_irq(lchip); for (i = 0; i < ARRAY_SIZE(locomo_devices); i++) - locomo_init_one_child(lchip, mem, &locomo_devices[i]); + locomo_init_one_child(lchip, &locomo_devices[i]); return 0; @@ -654,6 +718,238 @@ static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev) return (struct locomo *)dev_get_drvdata(ldev->dev.parent); } +void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int r; + + spin_lock_irqsave(&lchip->lock, flags); + + r = locomo_readl(lchip->base + LOCOMO_GPD); + r &= ~bits; + locomo_writel(r, lchip->base + LOCOMO_GPD); + + r = locomo_readl(lchip->base + LOCOMO_GPE); + if (dir) + r |= bits; + else + r &= ~bits; + locomo_writel(r, lchip->base + LOCOMO_GPE); + + spin_unlock_irqrestore(&lchip->lock, flags); +} + +unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&lchip->lock, flags); + ret = locomo_readl(lchip->base + LOCOMO_GPL); + spin_unlock_irqrestore(&lchip->lock, flags); + + ret &= bits; + return ret; +} + +unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&lchip->lock, flags); + ret = locomo_readl(lchip->base + LOCOMO_GPO); + spin_unlock_irqrestore(&lchip->lock, flags); + + ret &= bits; + return ret; +} + +void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int r; + + spin_lock_irqsave(&lchip->lock, flags); + + r = locomo_readl(lchip->base + LOCOMO_GPO); + if (set) + r |= bits; + else + r &= ~bits; + locomo_writel(r, lchip->base + LOCOMO_GPO); + + spin_unlock_irqrestore(&lchip->lock, flags); +} + +static void locomo_m62332_sendbit(void *mapbase, int bit) +{ + unsigned int r; + + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_DATA_HOLD_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + + if (bit & 1) { + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + } else { + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + } + + udelay(DAC_DATA_SETUP_TIME); /* 250 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.0 usec */ +} + +void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + int i; + unsigned char data; + unsigned int r; + void *mapbase = lchip->base; + unsigned long flags; + + spin_lock_irqsave(&lchip->lock, flags); + + /* Start */ + udelay(DAC_BUS_FREE_TIME); /* 5.0 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.0 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_START_HOLD_TIME); /* 5.0 usec */ + udelay(DAC_DATA_HOLD_TIME); /* 300 nsec */ + + /* Send slave address and W bit (LSB is W bit) */ + data = (M62332_SLAVE_ADDR << 1) | M62332_W_BIT; + for (i = 1; i <= 8; i++) { + locomo_m62332_sendbit(mapbase, data >> (8 - i)); + } + + /* Check A bit */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ + if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ + printk(KERN_WARNING "locomo: m62332_senddata Error 1\n"); + return; + } + + /* Send Sub address (LSB is channel select) */ + /* channel = 0 : ch1 select */ + /* = 1 : ch2 select */ + data = M62332_SUB_ADDR + channel; + for (i = 1; i <= 8; i++) { + locomo_m62332_sendbit(mapbase, data >> (8 - i)); + } + + /* Check A bit */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ + if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ + printk(KERN_WARNING "locomo: m62332_senddata Error 2\n"); + return; + } + + /* Send DAC data */ + for (i = 1; i <= 8; i++) { + locomo_m62332_sendbit(mapbase, dac_data >> (8 - i)); + } + + /* Check A bit */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ + if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ + printk(KERN_WARNING "locomo: m62332_senddata Error 3\n"); + return; + } + + /* stop */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */ + + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + + spin_unlock_irqrestore(&lchip->lock, flags); +} + /* * LoCoMo "Register Access Bus." * @@ -755,3 +1051,8 @@ MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>"); EXPORT_SYMBOL(locomo_driver_register); EXPORT_SYMBOL(locomo_driver_unregister); +EXPORT_SYMBOL(locomo_gpio_set_dir); +EXPORT_SYMBOL(locomo_gpio_read_level); +EXPORT_SYMBOL(locomo_gpio_read_output); +EXPORT_SYMBOL(locomo_gpio_write); +EXPORT_SYMBOL(locomo_m62332_senddata); diff --git a/include/asm-arm/hardware/locomo.h b/include/asm-arm/hardware/locomo.h index 98d6da2dc424..5f9218c15142 100644 --- a/include/asm-arm/hardware/locomo.h +++ b/include/asm-arm/hardware/locomo.h @@ -35,146 +35,139 @@ #define LOCOMO_MCSX3 0x1c /* Touch panel controller */ -#define LOCOMO_ASD 0x20 /* AD start delay */ -#define LOCOMO_HSD 0x28 /* HSYS delay */ -#define LOCOMO_HSC 0x2c /* HSYS period */ -#define LOCOMO_TADC 0x30 /* tablet ADC clock */ +#define LOCOMO_ASD 0x20 /* AD start delay */ +#define LOCOMO_HSD 0x28 /* HSYS delay */ +#define LOCOMO_HSC 0x2c /* HSYS period */ +#define LOCOMO_TADC 0x30 /* tablet ADC clock */ -/* TFT signal */ -#define LOCOMO_TC 0x38 /* TFT control signal */ -#define LOCOMO_CPSD 0x3c /* CPS delay */ - -/* Key controller */ -#define LOCOMO_KIB 0x40 /* KIB level */ -#define LOCOMO_KSC 0x44 /* KSTRB control */ -#define LOCOMO_KCMD 0x48 /* KSTRB command */ -#define LOCOMO_KIC 0x4c /* Key interrupt */ - -/* Audio clock */ -#define LOCOMO_ACC 0x54 - -/* SPI interface */ -#define LOCOMO_SPIMD 0x60 /* SPI mode setting */ -#define LOCOMO_SPICT 0x64 /* SPI mode control */ -#define LOCOMO_SPIST 0x68 /* SPI status */ -#define LOCOMO_SPIIS 0x70 /* SPI interrupt status */ -#define LOCOMO_SPIWE 0x74 /* SPI interrupt status write enable */ -#define LOCOMO_SPIIE 0x78 /* SPI interrupt enable */ -#define LOCOMO_SPIIR 0x7c /* SPI interrupt request */ -#define LOCOMO_SPITD 0x80 /* SPI transfer data write */ -#define LOCOMO_SPIRD 0x84 /* SPI receive data read */ -#define LOCOMO_SPITS 0x88 /* SPI transfer data shift */ -#define LOCOMO_SPIRS 0x8C /* SPI receive data shift */ - -#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */ -#define LOCOMO_SPI_OVRN (1 << 2) /* Over Run bit */ -#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */ -#define LOCOMO_SPI_RFR (1) /* read buffer bit */ - -/* GPIO */ -#define LOCOMO_GPD 0x90 /* GPIO direction */ -#define LOCOMO_GPE 0x94 /* GPIO input enable */ -#define LOCOMO_GPL 0x98 /* GPIO level */ -#define LOCOMO_GPO 0x9c /* GPIO out data setteing */ -#define LOCOMO_GRIE 0xa0 /* GPIO rise detection */ -#define LOCOMO_GFIE 0xa4 /* GPIO fall detection */ -#define LOCOMO_GIS 0xa8 /* GPIO edge detection status */ -#define LOCOMO_GWE 0xac /* GPIO status write enable */ -#define LOCOMO_GIE 0xb0 /* GPIO interrupt enable */ -#define LOCOMO_GIR 0xb4 /* GPIO interrupt request */ - -#define LOCOMO_GPIO0 (1<<0) -#define LOCOMO_GPIO1 (1<<1) -#define LOCOMO_GPIO2 (1<<2) -#define LOCOMO_GPIO3 (1<<3) -#define LOCOMO_GPIO4 (1<<4) -#define LOCOMO_GPIO5 (1<<5) -#define LOCOMO_GPIO6 (1<<6) -#define LOCOMO_GPIO7 (1<<7) -#define LOCOMO_GPIO8 (1<<8) -#define LOCOMO_GPIO9 (1<<9) -#define LOCOMO_GPIO10 (1<<10) -#define LOCOMO_GPIO11 (1<<11) -#define LOCOMO_GPIO12 (1<<12) -#define LOCOMO_GPIO13 (1<<13) -#define LOCOMO_GPIO14 (1<<14) -#define LOCOMO_GPIO15 (1<<15) - -/* Front light adjustment controller */ -#define LOCOMO_ALS 0xc8 /* Adjust light cycle */ -#define LOCOMO_ALD 0xcc /* Adjust light duty */ - -/* PCM audio interface */ -#define LOCOMO_PAIF 0xd0 /* Long time timer */ -#define LOCOMO_LTC 0xd8 /* LTC interrupt setting */ -#define LOCOMO_LTINT 0xdc /* LTC interrupt */ +#define LOCOMO_LTC 0xd8 /* LTC interrupt setting */ +#define LOCOMO_LTINT 0xdc /* LTC interrupt */ /* DAC control signal for LCD (COMADJ ) */ -#define LOCOMO_DAC 0xe0 - +#define LOCOMO_DAC 0xe0 /* DAC control */ #define LOCOMO_DAC_SCLOEB 0x08 /* SCL pin output data */ #define LOCOMO_DAC_TEST 0x04 /* Test bit */ #define LOCOMO_DAC_SDA 0x02 /* SDA pin level (read-only) */ #define LOCOMO_DAC_SDAOEB 0x01 /* SDA pin output data */ -/* LED controller */ -#define LOCOMO_LPT0 0xe8 /* LEDPWM0 timer */ -#define LOCOMO_LPT1 0xec /* LEDPWM1 timer */ +/* SPI interface */ +#define LOCOMO_SPIMD 0x60 /* SPI mode setting */ +#define LOCOMO_SPICT 0x64 /* SPI mode control */ +#define LOCOMO_SPIST 0x68 /* SPI status */ +#define LOCOMO_SPIIS 0x70 /* SPI interrupt status */ +#define LOCOMO_SPIWE 0x74 /* SPI interrupt status write enable */ +#define LOCOMO_SPIIE 0x78 /* SPI interrupt enable */ +#define LOCOMO_SPIIR 0x7c /* SPI interrupt request */ +#define LOCOMO_SPITD 0x80 /* SPI transfer data write */ +#define LOCOMO_SPIRD 0x84 /* SPI receive data read */ +#define LOCOMO_SPITS 0x88 /* SPI transfer data shift */ +#define LOCOMO_SPIRS 0x8C /* SPI receive data shift */ +#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */ +#define LOCOMO_SPI_OVRN (1 << 2) /* Over Run bit */ +#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */ +#define LOCOMO_SPI_RFR (1) /* read buffer bit */ -#define LOCOMO_LPT_TOFH 0x80 /* */ -#define LOCOMO_LPT_TOFL 0x08 /* */ -#define LOCOMO_LPT_TOH(TOH) ((TOH & 0x7) << 4) /* */ -#define LOCOMO_LPT_TOL(TOL) ((TOL & 0x7)) /* */ +/* GPIO */ +#define LOCOMO_GPD 0x90 /* GPIO direction */ +#define LOCOMO_GPE 0x94 /* GPIO input enable */ +#define LOCOMO_GPL 0x98 /* GPIO level */ +#define LOCOMO_GPO 0x9c /* GPIO out data setteing */ +#define LOCOMO_GRIE 0xa0 /* GPIO rise detection */ +#define LOCOMO_GFIE 0xa4 /* GPIO fall detection */ +#define LOCOMO_GIS 0xa8 /* GPIO edge detection status */ +#define LOCOMO_GWE 0xac /* GPIO status write enable */ +#define LOCOMO_GIE 0xb0 /* GPIO interrupt enable */ +#define LOCOMO_GIR 0xb4 /* GPIO interrupt request */ +#define LOCOMO_GPIO(Nb) (0x01 << (Nb)) +#define LOCOMO_GPIO_RTS LOCOMO_GPIO(0) +#define LOCOMO_GPIO_CTS LOCOMO_GPIO(1) +#define LOCOMO_GPIO_DSR LOCOMO_GPIO(2) +#define LOCOMO_GPIO_DTR LOCOMO_GPIO(3) +#define LOCOMO_GPIO_LCD_VSHA_ON LOCOMO_GPIO(4) +#define LOCOMO_GPIO_LCD_VSHD_ON LOCOMO_GPIO(5) +#define LOCOMO_GPIO_LCD_VEE_ON LOCOMO_GPIO(6) +#define LOCOMO_GPIO_LCD_MOD LOCOMO_GPIO(7) +#define LOCOMO_GPIO_DAC_ON LOCOMO_GPIO(8) +#define LOCOMO_GPIO_FL_VR LOCOMO_GPIO(9) +#define LOCOMO_GPIO_DAC_SDATA LOCOMO_GPIO(10) +#define LOCOMO_GPIO_DAC_SCK LOCOMO_GPIO(11) +#define LOCOMO_GPIO_DAC_SLOAD LOCOMO_GPIO(12) + +/* Start the definitions of the devices. Each device has an initial + * base address and a series of offsets from that base address. */ + +/* Keyboard controller */ +#define LOCOMO_KEYBOARD 0x40 +#define LOCOMO_KIB 0x00 /* KIB level */ +#define LOCOMO_KSC 0x04 /* KSTRB control */ +#define LOCOMO_KCMD 0x08 /* KSTRB command */ +#define LOCOMO_KIC 0x0c /* Key interrupt */ +/* Front light adjustment controller */ +#define LOCOMO_FRONTLIGHT 0xc8 +#define LOCOMO_ALS 0x00 /* Adjust light cycle */ +#define LOCOMO_ALD 0x04 /* Adjust light duty */ + +/* Backlight controller: TFT signal */ +#define LOCOMO_BACKLIGHT 0x38 +#define LOCOMO_TC 0x00 /* TFT control signal */ +#define LOCOMO_CPSD 0x04 /* CPS delay */ + +/* Audio controller */ +#define LOCOMO_AUDIO 0x54 +#define LOCOMO_ACC 0x00 /* Audio clock */ +#define LOCOMO_PAIF 0x7C /* PCM audio interface */ /* Audio clock */ -#define LOCOMO_ACC_XON 0x80 /* */ -#define LOCOMO_ACC_XEN 0x40 /* */ -#define LOCOMO_ACC_XSEL0 0x00 /* */ -#define LOCOMO_ACC_XSEL1 0x20 /* */ -#define LOCOMO_ACC_MCLKEN 0x10 /* */ -#define LOCOMO_ACC_64FSEN 0x08 /* */ +#define LOCOMO_ACC_XON 0x80 +#define LOCOMO_ACC_XEN 0x40 +#define LOCOMO_ACC_XSEL0 0x00 +#define LOCOMO_ACC_XSEL1 0x20 +#define LOCOMO_ACC_MCLKEN 0x10 +#define LOCOMO_ACC_64FSEN 0x08 #define LOCOMO_ACC_CLKSEL000 0x00 /* mclk 2 */ #define LOCOMO_ACC_CLKSEL001 0x01 /* mclk 3 */ #define LOCOMO_ACC_CLKSEL010 0x02 /* mclk 4 */ #define LOCOMO_ACC_CLKSEL011 0x03 /* mclk 6 */ #define LOCOMO_ACC_CLKSEL100 0x04 /* mclk 8 */ #define LOCOMO_ACC_CLKSEL101 0x05 /* mclk 12 */ - /* PCM audio interface */ -#define LOCOMO_PAIF_SCINV 0x20 /* */ -#define LOCOMO_PAIF_SCEN 0x10 /* */ -#define LOCOMO_PAIF_LRCRST 0x08 /* */ -#define LOCOMO_PAIF_LRCEVE 0x04 /* */ -#define LOCOMO_PAIF_LRCINV 0x02 /* */ -#define LOCOMO_PAIF_LRCEN 0x01 /* */ +#define LOCOMO_PAIF_SCINV 0x20 +#define LOCOMO_PAIF_SCEN 0x10 +#define LOCOMO_PAIF_LRCRST 0x08 +#define LOCOMO_PAIF_LRCEVE 0x04 +#define LOCOMO_PAIF_LRCINV 0x02 +#define LOCOMO_PAIF_LRCEN 0x01 -/* GPIO */ -#define LOCOMO_GPIO(Nb) (0x01 << (Nb)) /* LoCoMo GPIO [0...15] */ -#define LOCOMO_GPIO_RTS LOCOMO_GPIO(0) /* LoCoMo GPIO [0] */ -#define LOCOMO_GPIO_CTS LOCOMO_GPIO(1) /* LoCoMo GPIO [1] */ -#define LOCOMO_GPIO_DSR LOCOMO_GPIO(2) /* LoCoMo GPIO [2] */ -#define LOCOMO_GPIO_DTR LOCOMO_GPIO(3) /* LoCoMo GPIO [3] */ -#define LOCOMO_GPIO_LCD_VSHA_ON LOCOMO_GPIO(4) /* LoCoMo GPIO [4] */ -#define LOCOMO_GPIO_LCD_VSHD_ON LOCOMO_GPIO(5) /* LoCoMo GPIO [5] */ -#define LOCOMO_GPIO_LCD_VEE_ON LOCOMO_GPIO(6) /* LoCoMo GPIO [6] */ -#define LOCOMO_GPIO_LCD_MOD LOCOMO_GPIO(7) /* LoCoMo GPIO [7] */ -#define LOCOMO_GPIO_DAC_ON LOCOMO_GPIO(8) /* LoCoMo GPIO [8] */ -#define LOCOMO_GPIO_FL_VR LOCOMO_GPIO(9) /* LoCoMo GPIO [9] */ -#define LOCOMO_GPIO_DAC_SDATA LOCOMO_GPIO(10) /* LoCoMo GPIO [10] */ -#define LOCOMO_GPIO_DAC_SCK LOCOMO_GPIO(11) /* LoCoMo GPIO [11] */ -#define LOCOMO_GPIO_DAC_SLOAD LOCOMO_GPIO(12) /* LoCoMo GPIO [12] */ +/* LED controller */ +#define LOCOMO_LED 0xe8 +#define LOCOMO_LPT0 0x00 +#define LOCOMO_LPT1 0x04 +/* LED control */ +#define LOCOMO_LPT_TOFH 0x80 +#define LOCOMO_LPT_TOFL 0x08 +#define LOCOMO_LPT_TOH(TOH) ((TOH & 0x7) << 4) +#define LOCOMO_LPT_TOL(TOL) ((TOL & 0x7)) extern struct bus_type locomo_bus_type; +#define LOCOMO_DEVID_KEYBOARD 0 +#define LOCOMO_DEVID_FRONTLIGHT 1 +#define LOCOMO_DEVID_BACKLIGHT 2 +#define LOCOMO_DEVID_AUDIO 3 +#define LOCOMO_DEVID_LED 4 +#define LOCOMO_DEVID_UART 5 + struct locomo_dev { struct device dev; unsigned int devid; - struct resource res; - void *mapbase; unsigned int irq[1]; + + void *mapbase; + unsigned long length; + u64 dma_mask; }; @@ -201,4 +194,13 @@ void locomo_lcd_power(struct locomo_dev *, int, unsigned int); int locomo_driver_register(struct locomo_driver *); void locomo_driver_unregister(struct locomo_driver *); +/* GPIO control functions */ +void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir); +unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits); +unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits); +void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set); + +/* M62332 control function */ +void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel); + #endif |
