diff options
| author | Ian Molton <spyro@f2s.com> | 2008-07-15 10:09:43 -0400 |
|---|---|---|
| committer | Samuel Ortiz <sameo@openedhand.com> | 2008-08-10 14:09:50 -0400 |
| commit | 1f192015ca5b2f4d0a79c191f03f64e72fd8fc29 (patch) | |
| tree | 073e1bca0f1f32417da5756762f8f2d72105ba23 | |
| parent | d3a2f71853ce543c5515d4982e202751e15b0b6d (diff) | |
mfd: driver for the T7L66XB TMIO SoC
This patchset provides support for the core functinality of the T7L66XB
SoC from Toshiba. Supported in this patchset is the IRQ MUX, MMC controller
and NAND flash controller.
Signed-off-by: Ian Molton <spyro@f2s.com>
Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
| -rw-r--r-- | drivers/mfd/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mfd/t7l66xb.c | 409 | ||||
| -rw-r--r-- | include/linux/mfd/t7l66xb.h | 36 |
4 files changed, 452 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 883e7ea31de2..fc7c919693bf 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
| @@ -50,6 +50,12 @@ config HTC_PASIC3 | |||
| 50 | HTC Magician devices, respectively. Actual functionality is | 50 | HTC Magician devices, respectively. Actual functionality is |
| 51 | handled by the leds-pasic3 and ds1wm drivers. | 51 | handled by the leds-pasic3 and ds1wm drivers. |
| 52 | 52 | ||
| 53 | config MFD_T7L66XB | ||
| 54 | bool "Support Toshiba T7L66XB" | ||
| 55 | select MFD_CORE | ||
| 56 | help | ||
| 57 | Support for Toshiba Mobile IO Controller T7L66XB | ||
| 58 | |||
| 53 | config MFD_TC6393XB | 59 | config MFD_TC6393XB |
| 54 | bool "Support Toshiba TC6393XB" | 60 | bool "Support Toshiba TC6393XB" |
| 55 | depends on GPIOLIB && ARM | 61 | depends on GPIOLIB && ARM |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 33daa2f45dd8..3531ad2a276c 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
| @@ -8,6 +8,7 @@ obj-$(CONFIG_MFD_ASIC3) += asic3.o | |||
| 8 | obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o | 8 | obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o |
| 9 | obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o | 9 | obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o | ||
| 11 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o | 12 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o |
| 12 | 13 | ||
| 13 | obj-$(CONFIG_MFD_CORE) += mfd-core.o | 14 | obj-$(CONFIG_MFD_CORE) += mfd-core.o |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c new file mode 100644 index 000000000000..5be42054f739 --- /dev/null +++ b/drivers/mfd/t7l66xb.c | |||
| @@ -0,0 +1,409 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Toshiba T7L66XB core mfd support | ||
| 4 | * | ||
| 5 | * Copyright (c) 2005, 2007, 2008 Ian Molton | ||
| 6 | * Copyright (c) 2008 Dmitry Baryshkov | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * T7L66 features: | ||
| 13 | * | ||
| 14 | * Supported in this driver: | ||
| 15 | * SD/MMC | ||
| 16 | * SM/NAND flash controller | ||
| 17 | * | ||
| 18 | * As yet not supported | ||
| 19 | * GPIO interface (on NAND pins) | ||
| 20 | * Serial interface | ||
| 21 | * TFT 'interface converter' | ||
| 22 | * PCMCIA interface logic | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/io.h> | ||
| 28 | #include <linux/irq.h> | ||
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/mfd/core.h> | ||
| 31 | #include <linux/mfd/tmio.h> | ||
| 32 | #include <linux/mfd/t7l66xb.h> | ||
| 33 | |||
| 34 | enum { | ||
| 35 | T7L66XB_CELL_NAND, | ||
| 36 | T7L66XB_CELL_MMC, | ||
| 37 | }; | ||
| 38 | |||
| 39 | #define SCR_REVID 0x08 /* b Revision ID */ | ||
| 40 | #define SCR_IMR 0x42 /* b Interrupt Mask */ | ||
| 41 | #define SCR_DEV_CTL 0xe0 /* b Device control */ | ||
| 42 | #define SCR_ISR 0xe1 /* b Interrupt Status */ | ||
| 43 | #define SCR_GPO_OC 0xf0 /* b GPO output control */ | ||
| 44 | #define SCR_GPO_OS 0xf1 /* b GPO output enable */ | ||
| 45 | #define SCR_GPI_S 0xf2 /* w GPI status */ | ||
| 46 | #define SCR_APDC 0xf8 /* b Active pullup down ctrl */ | ||
| 47 | |||
| 48 | #define SCR_DEV_CTL_USB BIT(0) /* USB enable */ | ||
| 49 | #define SCR_DEV_CTL_MMC BIT(1) /* MMC enable */ | ||
| 50 | |||
| 51 | /*--------------------------------------------------------------------------*/ | ||
| 52 | |||
| 53 | struct t7l66xb { | ||
| 54 | void __iomem *scr; | ||
| 55 | /* Lock to protect registers requiring read/modify/write ops. */ | ||
| 56 | spinlock_t lock; | ||
| 57 | |||
| 58 | struct resource rscr; | ||
| 59 | int irq; | ||
| 60 | int irq_base; | ||
| 61 | }; | ||
| 62 | |||
| 63 | /*--------------------------------------------------------------------------*/ | ||
| 64 | |||
| 65 | static int t7l66xb_mmc_enable(struct platform_device *mmc) | ||
| 66 | { | ||
| 67 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
| 68 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; | ||
| 69 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | ||
| 70 | unsigned long flags; | ||
| 71 | u8 dev_ctl; | ||
| 72 | |||
| 73 | if (pdata->enable_clk32k) | ||
| 74 | pdata->enable_clk32k(dev); | ||
| 75 | |||
| 76 | spin_lock_irqsave(&t7l66xb->lock, flags); | ||
| 77 | |||
| 78 | dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); | ||
| 79 | dev_ctl |= SCR_DEV_CTL_MMC; | ||
| 80 | tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); | ||
| 81 | |||
| 82 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | ||
| 83 | |||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | static int t7l66xb_mmc_disable(struct platform_device *mmc) | ||
| 88 | { | ||
| 89 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | ||
| 90 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; | ||
| 91 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | ||
| 92 | unsigned long flags; | ||
| 93 | u8 dev_ctl; | ||
| 94 | |||
| 95 | spin_lock_irqsave(&t7l66xb->lock, flags); | ||
| 96 | |||
| 97 | dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); | ||
| 98 | dev_ctl &= ~SCR_DEV_CTL_MMC; | ||
| 99 | tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); | ||
| 100 | |||
| 101 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | ||
| 102 | |||
| 103 | if (pdata->disable_clk32k) | ||
| 104 | pdata->disable_clk32k(dev); | ||
| 105 | |||
| 106 | return 0; | ||
| 107 | } | ||
| 108 | |||
| 109 | /*--------------------------------------------------------------------------*/ | ||
| 110 | |||
| 111 | const static struct resource t7l66xb_mmc_resources[] = { | ||
| 112 | { | ||
| 113 | .start = 0x800, | ||
| 114 | .end = 0x9ff, | ||
| 115 | .flags = IORESOURCE_MEM, | ||
| 116 | }, | ||
| 117 | { | ||
| 118 | .start = 0x200, | ||
| 119 | .end = 0x2ff, | ||
| 120 | .flags = IORESOURCE_MEM, | ||
| 121 | }, | ||
| 122 | { | ||
| 123 | .start = IRQ_T7L66XB_MMC, | ||
| 124 | .end = IRQ_T7L66XB_MMC, | ||
| 125 | .flags = IORESOURCE_IRQ, | ||
| 126 | }, | ||
| 127 | }; | ||
| 128 | |||
| 129 | const static struct resource t7l66xb_nand_resources[] = { | ||
| 130 | { | ||
| 131 | .start = 0xc00, | ||
| 132 | .end = 0xc07, | ||
| 133 | .flags = IORESOURCE_MEM, | ||
| 134 | }, | ||
| 135 | { | ||
| 136 | .start = 0x0100, | ||
| 137 | .end = 0x01ff, | ||
| 138 | .flags = IORESOURCE_MEM, | ||
| 139 | }, | ||
| 140 | { | ||
| 141 | .start = IRQ_T7L66XB_NAND, | ||
| 142 | .end = IRQ_T7L66XB_NAND, | ||
| 143 | .flags = IORESOURCE_IRQ, | ||
| 144 | }, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static struct mfd_cell t7l66xb_cells[] = { | ||
| 148 | [T7L66XB_CELL_MMC] = { | ||
| 149 | .name = "tmio-mmc", | ||
| 150 | .enable = t7l66xb_mmc_enable, | ||
| 151 | .disable = t7l66xb_mmc_disable, | ||
| 152 | .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), | ||
| 153 | .resources = t7l66xb_mmc_resources, | ||
| 154 | }, | ||
| 155 | [T7L66XB_CELL_NAND] = { | ||
| 156 | .name = "tmio-nand", | ||
| 157 | .num_resources = ARRAY_SIZE(t7l66xb_nand_resources), | ||
| 158 | .resources = t7l66xb_nand_resources, | ||
| 159 | }, | ||
| 160 | }; | ||
| 161 | |||
| 162 | /*--------------------------------------------------------------------------*/ | ||
| 163 | |||
| 164 | /* Handle the T7L66XB interrupt mux */ | ||
| 165 | static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) | ||
| 166 | { | ||
| 167 | struct t7l66xb *t7l66xb = get_irq_data(irq); | ||
| 168 | unsigned int isr; | ||
| 169 | unsigned int i, irq_base; | ||
