Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Toshiba TC6393XB SoC support
0004  *
0005  * Copyright(c) 2005-2006 Chris Humbert
0006  * Copyright(c) 2005 Dirk Opfer
0007  * Copyright(c) 2005 Ian Molton <spyro@f2s.com>
0008  * Copyright(c) 2007 Dmitry Baryshkov
0009  *
0010  * Based on code written by Sharp/Lineo for 2.4 kernels
0011  * Based on locomo.c
0012  */
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/io.h>
0017 #include <linux/irq.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/clk.h>
0020 #include <linux/err.h>
0021 #include <linux/mfd/core.h>
0022 #include <linux/mfd/tmio.h>
0023 #include <linux/mfd/tc6393xb.h>
0024 #include <linux/gpio/driver.h>
0025 #include <linux/gpio/machine.h>
0026 #include <linux/gpio/consumer.h>
0027 #include <linux/slab.h>
0028 
0029 #define SCR_REVID   0x08        /* b Revision ID    */
0030 #define SCR_ISR     0x50        /* b Interrupt Status   */
0031 #define SCR_IMR     0x52        /* b Interrupt Mask */
0032 #define SCR_IRR     0x54        /* b Interrupt Routing  */
0033 #define SCR_GPER    0x60        /* w GP Enable      */
0034 #define SCR_GPI_SR(i)   (0x64 + (i))    /* b3 GPI Status    */
0035 #define SCR_GPI_IMR(i)  (0x68 + (i))    /* b3 GPI INT Mask  */
0036 #define SCR_GPI_EDER(i) (0x6c + (i))    /* b3 GPI Edge Detect Enable */
0037 #define SCR_GPI_LIR(i)  (0x70 + (i))    /* b3 GPI Level Invert  */
0038 #define SCR_GPO_DSR(i)  (0x78 + (i))    /* b3 GPO Data Set  */
0039 #define SCR_GPO_DOECR(i) (0x7c + (i))   /* b3 GPO Data OE Control */
0040 #define SCR_GP_IARCR(i) (0x80 + (i))    /* b3 GP Internal Active Register Control */
0041 #define SCR_GP_IARLCR(i) (0x84 + (i))   /* b3 GP INTERNAL Active Register Level Control */
0042 #define SCR_GPI_BCR(i)  (0x88 + (i))    /* b3 GPI Buffer Control */
0043 #define SCR_GPA_IARCR   0x8c        /* w GPa Internal Active Register Control */
0044 #define SCR_GPA_IARLCR  0x90        /* w GPa Internal Active Register Level Control */
0045 #define SCR_GPA_BCR 0x94        /* w GPa Buffer Control */
0046 #define SCR_CCR     0x98        /* w Clock Control  */
0047 #define SCR_PLL2CR  0x9a        /* w PLL2 Control   */
0048 #define SCR_PLL1CR  0x9c        /* l PLL1 Control   */
0049 #define SCR_DIARCR  0xa0        /* b Device Internal Active Register Control */
0050 #define SCR_DBOCR   0xa1        /* b Device Buffer Off Control */
0051 #define SCR_FER     0xe0        /* b Function Enable    */
0052 #define SCR_MCR     0xe4        /* w Mode Control   */
0053 #define SCR_CONFIG  0xfc        /* b Configuration Control */
0054 #define SCR_DEBUG   0xff        /* b Debug      */
0055 
0056 #define SCR_CCR_CK32K   BIT(0)
0057 #define SCR_CCR_USBCK   BIT(1)
0058 #define SCR_CCR_UNK1    BIT(4)
0059 #define SCR_CCR_MCLK_MASK   (7 << 8)
0060 #define SCR_CCR_MCLK_OFF    (0 << 8)
0061 #define SCR_CCR_MCLK_12 (1 << 8)
0062 #define SCR_CCR_MCLK_24 (2 << 8)
0063 #define SCR_CCR_MCLK_48 (3 << 8)
0064 #define SCR_CCR_HCLK_MASK   (3 << 12)
0065 #define SCR_CCR_HCLK_24 (0 << 12)
0066 #define SCR_CCR_HCLK_48 (1 << 12)
0067 
0068 #define SCR_FER_USBEN       BIT(0)  /* USB host enable */
0069 #define SCR_FER_LCDCVEN     BIT(1)  /* polysilicon TFT enable */
0070 #define SCR_FER_SLCDEN      BIT(2)  /* SLCD enable */
0071 
0072 #define SCR_MCR_RDY_MASK        (3 << 0)
0073 #define SCR_MCR_RDY_OPENDRAIN   (0 << 0)
0074 #define SCR_MCR_RDY_TRISTATE    (1 << 0)
0075 #define SCR_MCR_RDY_PUSHPULL    (2 << 0)
0076 #define SCR_MCR_RDY_UNK     BIT(2)
0077 #define SCR_MCR_RDY_EN      BIT(3)
0078 #define SCR_MCR_INT_MASK        (3 << 4)
0079 #define SCR_MCR_INT_OPENDRAIN   (0 << 4)
0080 #define SCR_MCR_INT_TRISTATE    (1 << 4)
0081 #define SCR_MCR_INT_PUSHPULL    (2 << 4)
0082 #define SCR_MCR_INT_UNK     BIT(6)
0083 #define SCR_MCR_INT_EN      BIT(7)
0084 /* bits 8 - 16 are unknown */
0085 
0086 #define TC_GPIO_BIT(i)      (1 << (i & 0x7))
0087 
0088 /*--------------------------------------------------------------------------*/
0089 
0090 struct tc6393xb {
0091     void __iomem        *scr;
0092     struct device       *dev;
0093 
0094     struct gpio_chip    gpio;
0095     struct gpio_desc    *vcc_on;
0096 
0097     struct clk      *clk; /* 3,6 Mhz */
0098 
0099     raw_spinlock_t      lock; /* protects RMW cycles */
0100 
0101     struct {
0102         u8      fer;
0103         u16     ccr;
0104         u8      gpi_bcr[3];
0105         u8      gpo_dsr[3];
0106         u8      gpo_doecr[3];
0107     } suspend_state;
0108 
0109     struct resource     rscr;
0110     struct resource     *iomem;
0111     int         irq;
0112     int         irq_base;
0113 };
0114 
0115 enum {
0116     TC6393XB_CELL_NAND,
0117     TC6393XB_CELL_MMC,
0118     TC6393XB_CELL_OHCI,
0119     TC6393XB_CELL_FB,
0120 };
0121 
0122 /*--------------------------------------------------------------------------*/
0123 
0124 static int tc6393xb_nand_enable(struct platform_device *nand)
0125 {
0126     struct tc6393xb *tc6393xb = dev_get_drvdata(nand->dev.parent);
0127     unsigned long flags;
0128 
0129     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0130 
0131     /* SMD buffer on */
0132     dev_dbg(nand->dev.parent, "SMD buffer on\n");
0133     tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
0134 
0135     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0136 
0137     return 0;
0138 }
0139 
0140 static const struct resource tc6393xb_nand_resources[] = {
0141     {
0142         .start  = 0x1000,
0143         .end    = 0x1007,
0144         .flags  = IORESOURCE_MEM,
0145     },
0146     {
0147         .start  = 0x0100,
0148         .end    = 0x01ff,
0149         .flags  = IORESOURCE_MEM,
0150     },
0151     {
0152         .start  = IRQ_TC6393_NAND,
0153         .end    = IRQ_TC6393_NAND,
0154         .flags  = IORESOURCE_IRQ,
0155     },
0156 };
0157 
0158 static const struct resource tc6393xb_mmc_resources[] = {
0159     {
0160         .start  = 0x800,
0161         .end    = 0x9ff,
0162         .flags  = IORESOURCE_MEM,
0163     },
0164     {
0165         .start  = IRQ_TC6393_MMC,
0166         .end    = IRQ_TC6393_MMC,
0167         .flags  = IORESOURCE_IRQ,
0168     },
0169 };
0170 
0171 static const struct resource tc6393xb_ohci_resources[] = {
0172     {
0173         .start  = 0x3000,
0174         .end    = 0x31ff,
0175         .flags  = IORESOURCE_MEM,
0176     },
0177     {
0178         .start  = 0x0300,
0179         .end    = 0x03ff,
0180         .flags  = IORESOURCE_MEM,
0181     },
0182     {
0183         .start  = 0x010000,
0184         .end    = 0x017fff,
0185         .flags  = IORESOURCE_MEM,
0186     },
0187     {
0188         .start  = 0x018000,
0189         .end    = 0x01ffff,
0190         .flags  = IORESOURCE_MEM,
0191     },
0192     {
0193         .start  = IRQ_TC6393_OHCI,
0194         .end    = IRQ_TC6393_OHCI,
0195         .flags  = IORESOURCE_IRQ,
0196     },
0197 };
0198 
0199 static const struct resource tc6393xb_fb_resources[] = {
0200     {
0201         .start  = 0x5000,
0202         .end    = 0x51ff,
0203         .flags  = IORESOURCE_MEM,
0204     },
0205     {
0206         .start  = 0x0500,
0207         .end    = 0x05ff,
0208         .flags  = IORESOURCE_MEM,
0209     },
0210     {
0211         .start  = 0x100000,
0212         .end    = 0x1fffff,
0213         .flags  = IORESOURCE_MEM,
0214     },
0215     {
0216         .start  = IRQ_TC6393_FB,
0217         .end    = IRQ_TC6393_FB,
0218         .flags  = IORESOURCE_IRQ,
0219     },
0220 };
0221 
0222 static int tc6393xb_ohci_enable(struct platform_device *dev)
0223 {
0224     struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
0225     unsigned long flags;
0226     u16 ccr;
0227     u8 fer;
0228 
0229     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0230 
0231     ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
0232     ccr |= SCR_CCR_USBCK;
0233     tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
0234 
0235     fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
0236     fer |= SCR_FER_USBEN;
0237     tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
0238 
0239     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0240 
0241     return 0;
0242 }
0243 
0244 static int tc6393xb_ohci_disable(struct platform_device *dev)
0245 {
0246     struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
0247     unsigned long flags;
0248     u16 ccr;
0249     u8 fer;
0250 
0251     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0252 
0253     fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
0254     fer &= ~SCR_FER_USBEN;
0255     tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
0256 
0257     ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
0258     ccr &= ~SCR_CCR_USBCK;
0259     tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
0260 
0261     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0262 
0263     return 0;
0264 }
0265 
0266 static int tc6393xb_ohci_suspend(struct platform_device *dev)
0267 {
0268     struct tc6393xb_platform_data *tcpd = dev_get_platdata(dev->dev.parent);
0269 
0270     /* We can't properly store/restore OHCI state, so fail here */
0271     if (tcpd->resume_restore)
0272         return -EBUSY;
0273 
0274     return tc6393xb_ohci_disable(dev);
0275 }
0276 
0277 static int tc6393xb_fb_enable(struct platform_device *dev)
0278 {
0279     struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
0280     unsigned long flags;
0281     u16 ccr;
0282 
0283     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0284 
0285     ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
0286     ccr &= ~SCR_CCR_MCLK_MASK;
0287     ccr |= SCR_CCR_MCLK_48;
0288     tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
0289 
0290     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0291 
0292     return 0;
0293 }
0294 
0295 static int tc6393xb_fb_disable(struct platform_device *dev)
0296 {
0297     struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
0298     unsigned long flags;
0299     u16 ccr;
0300 
0301     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0302 
0303     ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
0304     ccr &= ~SCR_CCR_MCLK_MASK;
0305     ccr |= SCR_CCR_MCLK_OFF;
0306     tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
0307 
0308     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0309 
0310     return 0;
0311 }
0312 
0313 int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
0314 {
0315     struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent);
0316     u8 fer;
0317     unsigned long flags;
0318 
0319     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0320 
0321     fer = ioread8(tc6393xb->scr + SCR_FER);
0322     if (on)
0323         fer |= SCR_FER_SLCDEN;
0324     else
0325         fer &= ~SCR_FER_SLCDEN;
0326     iowrite8(fer, tc6393xb->scr + SCR_FER);
0327 
0328     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0329 
0330     return 0;
0331 }
0332 EXPORT_SYMBOL(tc6393xb_lcd_set_power);
0333 
0334 int tc6393xb_lcd_mode(struct platform_device *fb,
0335                     const struct fb_videomode *mode) {
0336     struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent);
0337     unsigned long flags;
0338 
0339     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0340 
0341     iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0);
0342     iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2);
0343 
0344     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0345 
0346     return 0;
0347 }
0348 EXPORT_SYMBOL(tc6393xb_lcd_mode);
0349 
0350 static int tc6393xb_mmc_enable(struct platform_device *mmc)
0351 {
0352     struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
0353 
0354     tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0,
0355         tc6393xb_mmc_resources[0].start & 0xfffe);
0356 
0357     return 0;
0358 }
0359 
0360 static int tc6393xb_mmc_resume(struct platform_device *mmc)
0361 {
0362     struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
0363 
0364     tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0,
0365         tc6393xb_mmc_resources[0].start & 0xfffe);
0366 
0367     return 0;
0368 }
0369 
0370 static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state)
0371 {
0372     struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
0373 
0374     tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state);
0375 }
0376 
0377 static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state)
0378 {
0379     struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
0380 
0381     tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state);
0382 }
0383 
0384 static struct tmio_mmc_data tc6393xb_mmc_data = {
0385     .hclk = 24000000,
0386     .set_pwr = tc6393xb_mmc_pwr,
0387     .set_clk_div = tc6393xb_mmc_clk_div,
0388 };
0389 
0390 static struct mfd_cell tc6393xb_cells[] = {
0391     [TC6393XB_CELL_NAND] = {
0392         .name = "tmio-nand",
0393         .enable = tc6393xb_nand_enable,
0394         .num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
0395         .resources = tc6393xb_nand_resources,
0396     },
0397     [TC6393XB_CELL_MMC] = {
0398         .name = "tmio-mmc",
0399         .enable = tc6393xb_mmc_enable,
0400         .resume = tc6393xb_mmc_resume,
0401         .platform_data = &tc6393xb_mmc_data,
0402         .pdata_size    = sizeof(tc6393xb_mmc_data),
0403         .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
0404         .resources = tc6393xb_mmc_resources,
0405     },
0406     [TC6393XB_CELL_OHCI] = {
0407         .name = "tmio-ohci",
0408         .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources),
0409         .resources = tc6393xb_ohci_resources,
0410         .enable = tc6393xb_ohci_enable,
0411         .suspend = tc6393xb_ohci_suspend,
0412         .resume = tc6393xb_ohci_enable,
0413         .disable = tc6393xb_ohci_disable,
0414     },
0415     [TC6393XB_CELL_FB] = {
0416         .name = "tmio-fb",
0417         .num_resources = ARRAY_SIZE(tc6393xb_fb_resources),
0418         .resources = tc6393xb_fb_resources,
0419         .enable = tc6393xb_fb_enable,
0420         .suspend = tc6393xb_fb_disable,
0421         .resume = tc6393xb_fb_enable,
0422         .disable = tc6393xb_fb_disable,
0423     },
0424 };
0425 
0426 /*--------------------------------------------------------------------------*/
0427 
0428 static int tc6393xb_gpio_get(struct gpio_chip *chip,
0429         unsigned offset)
0430 {
0431     struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
0432 
0433     /* XXX: does dsr also represent inputs? */
0434     return !!(tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
0435           & TC_GPIO_BIT(offset));
0436 }
0437 
0438 static void __tc6393xb_gpio_set(struct gpio_chip *chip,
0439         unsigned offset, int value)
0440 {
0441     struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
0442     u8  dsr;
0443 
0444     dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
0445     if (value)
0446         dsr |= TC_GPIO_BIT(offset);
0447     else
0448         dsr &= ~TC_GPIO_BIT(offset);
0449 
0450     tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
0451 }
0452 
0453 static void tc6393xb_gpio_set(struct gpio_chip *chip,
0454         unsigned offset, int value)
0455 {
0456     struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
0457     unsigned long flags;
0458 
0459     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0460 
0461     __tc6393xb_gpio_set(chip, offset, value);
0462 
0463     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0464 }
0465 
0466 static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
0467             unsigned offset)
0468 {
0469     struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
0470     unsigned long flags;
0471     u8 doecr;
0472 
0473     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0474 
0475     doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
0476     doecr &= ~TC_GPIO_BIT(offset);
0477     tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
0478 
0479     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0480 
0481     return 0;
0482 }
0483 
0484 static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
0485             unsigned offset, int value)
0486 {
0487     struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
0488     unsigned long flags;
0489     u8 doecr;
0490 
0491     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0492 
0493     __tc6393xb_gpio_set(chip, offset, value);
0494 
0495     doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
0496     doecr |= TC_GPIO_BIT(offset);
0497     tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
0498 
0499     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0500 
0501     return 0;
0502 }
0503 
0504 /*
0505  * TC6393XB GPIOs as used on TOSA, are the only user of this chip.
0506  * GPIOs 2, 5, 8 and 13 are not connected.
0507  */
0508 #define TOSA_GPIO_TG_ON         0
0509 #define TOSA_GPIO_L_MUTE        1
0510 #define TOSA_GPIO_BL_C20MA      3
0511 #define TOSA_GPIO_CARD_VCC_ON       4
0512 #define TOSA_GPIO_CHARGE_OFF        6
0513 #define TOSA_GPIO_CHARGE_OFF_JC     7
0514 #define TOSA_GPIO_BAT0_V_ON     9
0515 #define TOSA_GPIO_BAT1_V_ON     10
0516 #define TOSA_GPIO_BU_CHRG_ON        11
0517 #define TOSA_GPIO_BAT_SW_ON     12
0518 #define TOSA_GPIO_BAT0_TH_ON        14
0519 #define TOSA_GPIO_BAT1_TH_ON        15
0520 
0521 
0522 GPIO_LOOKUP_SINGLE(tosa_lcd_gpio_lookup, "spi2.0", "tc6393xb",
0523            TOSA_GPIO_TG_ON, "tg #pwr", GPIO_ACTIVE_HIGH);
0524 
0525 GPIO_LOOKUP_SINGLE(tosa_lcd_bl_gpio_lookup, "i2c-tos-bl", "tc6393xb",
0526            TOSA_GPIO_BL_C20MA, "backlight", GPIO_ACTIVE_HIGH);
0527 
0528 GPIO_LOOKUP_SINGLE(tosa_audio_gpio_lookup, "tosa-audio", "tc6393xb",
0529            TOSA_GPIO_L_MUTE, NULL, GPIO_ACTIVE_HIGH);
0530 
0531 static struct gpiod_lookup_table tosa_battery_gpio_lookup = {
0532     .dev_id = "wm97xx-battery",
0533     .table = {
0534         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF,
0535                 "main charge off", GPIO_ACTIVE_HIGH),
0536         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC,
0537                 "jacket charge off", GPIO_ACTIVE_HIGH),
0538         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_V_ON,
0539                 "main battery", GPIO_ACTIVE_HIGH),
0540         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_V_ON,
0541                 "jacket battery", GPIO_ACTIVE_HIGH),
0542         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BU_CHRG_ON,
0543                 "backup battery", GPIO_ACTIVE_HIGH),
0544         /* BAT1 and BAT0 thermistors appear to be swapped */
0545         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON,
0546                 "main battery temp", GPIO_ACTIVE_HIGH),
0547         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_TH_ON,
0548                 "jacket battery temp", GPIO_ACTIVE_HIGH),
0549         GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT_SW_ON,
0550                 "battery switch", GPIO_ACTIVE_HIGH),
0551         { },
0552     },
0553 };
0554 
0555 static struct gpiod_lookup_table *tc6393xb_gpio_lookups[] = {
0556     &tosa_lcd_gpio_lookup,
0557     &tosa_lcd_bl_gpio_lookup,
0558     &tosa_audio_gpio_lookup,
0559     &tosa_battery_gpio_lookup,
0560 };
0561 
0562 static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb)
0563 {
0564     struct gpio_chip *gc = &tc6393xb->gpio;
0565     struct device *dev = tc6393xb->dev;
0566     int ret;
0567 
0568     gc->label = "tc6393xb";
0569     gc->base = -1; /* Dynamic allocation */
0570     gc->ngpio = 16;
0571     gc->set = tc6393xb_gpio_set;
0572     gc->get = tc6393xb_gpio_get;
0573     gc->direction_input = tc6393xb_gpio_direction_input;
0574     gc->direction_output = tc6393xb_gpio_direction_output;
0575 
0576     ret = devm_gpiochip_add_data(dev, gc, tc6393xb);
0577     if (ret)
0578         return dev_err_probe(dev, ret, "failed to add GPIO chip\n");
0579 
0580     /* Register descriptor look-ups for consumers */
0581     gpiod_add_lookup_tables(tc6393xb_gpio_lookups, ARRAY_SIZE(tc6393xb_gpio_lookups));
0582 
0583     /* Request some of our own GPIOs */
0584     tc6393xb->vcc_on = gpiochip_request_own_desc(gc, TOSA_GPIO_CARD_VCC_ON, "VCC ON",
0585                              GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH);
0586     if (IS_ERR(tc6393xb->vcc_on))
0587         return dev_err_probe(dev, PTR_ERR(tc6393xb->vcc_on),
0588                      "failed to request VCC ON GPIO\n");
0589 
0590     return 0;
0591 }
0592 
0593 /*--------------------------------------------------------------------------*/
0594 
0595 static void tc6393xb_irq(struct irq_desc *desc)
0596 {
0597     struct tc6393xb *tc6393xb = irq_desc_get_handler_data(desc);
0598     unsigned int isr;
0599     unsigned int i, irq_base;
0600 
0601     irq_base = tc6393xb->irq_base;
0602 
0603     while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) &
0604                 ~tmio_ioread8(tc6393xb->scr + SCR_IMR)))
0605         for (i = 0; i < TC6393XB_NR_IRQS; i++) {
0606             if (isr & (1 << i))
0607                 generic_handle_irq(irq_base + i);
0608         }
0609 }
0610 
0611 static void tc6393xb_irq_ack(struct irq_data *data)
0612 {
0613 }
0614 
0615 static void tc6393xb_irq_mask(struct irq_data *data)
0616 {
0617     struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
0618     unsigned long flags;
0619     u8 imr;
0620 
0621     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0622     imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
0623     imr |= 1 << (data->irq - tc6393xb->irq_base);
0624     tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
0625     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0626 }
0627 
0628 static void tc6393xb_irq_unmask(struct irq_data *data)
0629 {
0630     struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
0631     unsigned long flags;
0632     u8 imr;
0633 
0634     raw_spin_lock_irqsave(&tc6393xb->lock, flags);
0635     imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
0636     imr &= ~(1 << (data->irq - tc6393xb->irq_base));
0637     tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
0638     raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
0639 }
0640 
0641 static struct irq_chip tc6393xb_chip = {
0642     .name       = "tc6393xb",
0643     .irq_ack    = tc6393xb_irq_ack,
0644     .irq_mask   = tc6393xb_irq_mask,
0645     .irq_unmask = tc6393xb_irq_unmask,
0646 };
0647 
0648 static void tc6393xb_attach_irq(struct platform_device *dev)
0649 {
0650     struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
0651     unsigned int irq, irq_base;
0652 
0653     irq_base = tc6393xb->irq_base;
0654 
0655     for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
0656         irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq);
0657         irq_set_chip_data(irq, tc6393xb);
0658         irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
0659     }
0660 
0661     irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING);
0662     irq_set_chained_handler_and_data(tc6393xb->irq, tc6393xb_irq,
0663                      tc6393xb);
0664 }
0665 
0666 static void tc6393xb_detach_irq(struct platform_device *dev)
0667 {
0668     struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
0669     unsigned int irq, irq_base;
0670 
0671     irq_set_chained_handler_and_data(tc6393xb->irq, NULL, NULL);
0672 
0673     irq_base = tc6393xb->irq_base;
0674 
0675     for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
0676         irq_set_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
0677         irq_set_chip(irq, NULL);
0678         irq_set_chip_data(irq, NULL);
0679     }
0680 }
0681 
0682 /*--------------------------------------------------------------------------*/
0683 
0684 static int tc6393xb_probe(struct platform_device *dev)
0685 {
0686     struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
0687     struct tc6393xb *tc6393xb;
0688     struct resource *iomem, *rscr;
0689     int ret;
0690 
0691     iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
0692     if (!iomem)
0693         return -EINVAL;
0694 
0695     tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
0696     if (!tc6393xb) {
0697         ret = -ENOMEM;
0698         goto err_kzalloc;
0699     }
0700     tc6393xb->dev = &dev->dev;
0701 
0702     raw_spin_lock_init(&tc6393xb->lock);
0703 
0704     platform_set_drvdata(dev, tc6393xb);
0705 
0706     ret = platform_get_irq(dev, 0);
0707     if (ret >= 0)
0708         tc6393xb->irq = ret;
0709     else
0710         goto err_noirq;
0711 
0712     tc6393xb->iomem = iomem;
0713     tc6393xb->irq_base = tcpd->irq_base;
0714 
0715     tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI");
0716     if (IS_ERR(tc6393xb->clk)) {
0717         ret = PTR_ERR(tc6393xb->clk);
0718         goto err_clk_get;
0719     }
0720 
0721     rscr = &tc6393xb->rscr;
0722     rscr->name = "tc6393xb-core";
0723     rscr->start = iomem->start;
0724     rscr->end = iomem->start + 0xff;
0725     rscr->flags = IORESOURCE_MEM;
0726 
0727     ret = request_resource(iomem, rscr);
0728     if (ret)
0729         goto err_request_scr;
0730 
0731     tc6393xb->scr = ioremap(rscr->start, resource_size(rscr));
0732     if (!tc6393xb->scr) {
0733         ret = -ENOMEM;
0734         goto err_ioremap;
0735     }
0736 
0737     ret = clk_prepare_enable(tc6393xb->clk);
0738     if (ret)
0739         goto err_clk_enable;
0740 
0741     ret = tcpd->enable(dev);
0742     if (ret)
0743         goto err_enable;
0744 
0745     iowrite8(0,             tc6393xb->scr + SCR_FER);
0746     iowrite16(tcpd->scr_pll2cr,     tc6393xb->scr + SCR_PLL2CR);
0747     iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48,
0748                         tc6393xb->scr + SCR_CCR);
0749     iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
0750           SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
0751           BIT(15),          tc6393xb->scr + SCR_MCR);
0752     iowrite16(tcpd->scr_gper,       tc6393xb->scr + SCR_GPER);
0753     iowrite8(0,             tc6393xb->scr + SCR_IRR);
0754     iowrite8(0xbf,              tc6393xb->scr + SCR_IMR);
0755 
0756     printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
0757             tmio_ioread8(tc6393xb->scr + SCR_REVID),
0758             (unsigned long) iomem->start, tc6393xb->irq);
0759 
0760     ret = tc6393xb_register_gpio(tc6393xb);
0761     if (ret)
0762         goto err_gpio_add;
0763 
0764     tc6393xb_attach_irq(dev);
0765 
0766     tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data;
0767     tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size =
0768                         sizeof(*tcpd->nand_data);
0769     tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data;
0770     tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data);
0771 
0772     ret = mfd_add_devices(&dev->dev, dev->id,
0773                   tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
0774                   iomem, tcpd->irq_base, NULL);
0775 
0776     if (!ret)
0777         return 0;
0778 
0779     tc6393xb_detach_irq(dev);
0780 err_gpio_add:
0781     tcpd->disable(dev);
0782 err_enable:
0783     clk_disable_unprepare(tc6393xb->clk);
0784 err_clk_enable:
0785     iounmap(tc6393xb->scr);
0786 err_ioremap:
0787     release_resource(&tc6393xb->rscr);
0788 err_request_scr:
0789     clk_put(tc6393xb->clk);
0790 err_noirq:
0791 err_clk_get:
0792     kfree(tc6393xb);
0793 err_kzalloc:
0794     return ret;
0795 }
0796 
0797 static int tc6393xb_remove(struct platform_device *dev)
0798 {
0799     struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
0800     struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
0801 
0802     mfd_remove_devices(&dev->dev);
0803 
0804     tc6393xb_detach_irq(dev);
0805 
0806     tcpd->disable(dev);
0807     clk_disable_unprepare(tc6393xb->clk);
0808     iounmap(tc6393xb->scr);
0809     release_resource(&tc6393xb->rscr);
0810     clk_put(tc6393xb->clk);
0811     kfree(tc6393xb);
0812 
0813     return 0;
0814 }
0815 
0816 #ifdef CONFIG_PM
0817 static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
0818 {
0819     struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
0820     struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
0821     int i, ret;
0822 
0823     tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR);
0824     tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER);
0825 
0826     for (i = 0; i < 3; i++) {
0827         tc6393xb->suspend_state.gpo_dsr[i] =
0828             ioread8(tc6393xb->scr + SCR_GPO_DSR(i));
0829         tc6393xb->suspend_state.gpo_doecr[i] =
0830             ioread8(tc6393xb->scr + SCR_GPO_DOECR(i));
0831         tc6393xb->suspend_state.gpi_bcr[i] =
0832             ioread8(tc6393xb->scr + SCR_GPI_BCR(i));
0833     }
0834     ret = tcpd->suspend(dev);
0835     clk_disable_unprepare(tc6393xb->clk);
0836 
0837     return ret;
0838 }
0839 
0840 static int tc6393xb_resume(struct platform_device *dev)
0841 {
0842     struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
0843     struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
0844     int ret;
0845     int i;
0846 
0847     ret = clk_prepare_enable(tc6393xb->clk);
0848     if (ret)
0849         return ret;
0850 
0851     ret = tcpd->resume(dev);
0852     if (ret)
0853         return ret;
0854 
0855     if (!tcpd->resume_restore)
0856         return 0;
0857 
0858     iowrite8(tc6393xb->suspend_state.fer,   tc6393xb->scr + SCR_FER);
0859     iowrite16(tcpd->scr_pll2cr,     tc6393xb->scr + SCR_PLL2CR);
0860     iowrite16(tc6393xb->suspend_state.ccr,  tc6393xb->scr + SCR_CCR);
0861     iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
0862           SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
0863           BIT(15),          tc6393xb->scr + SCR_MCR);
0864     iowrite16(tcpd->scr_gper,       tc6393xb->scr + SCR_GPER);
0865     iowrite8(0,             tc6393xb->scr + SCR_IRR);
0866     iowrite8(0xbf,              tc6393xb->scr + SCR_IMR);
0867 
0868     for (i = 0; i < 3; i++) {
0869         iowrite8(tc6393xb->suspend_state.gpo_dsr[i],
0870                     tc6393xb->scr + SCR_GPO_DSR(i));
0871         iowrite8(tc6393xb->suspend_state.gpo_doecr[i],
0872                     tc6393xb->scr + SCR_GPO_DOECR(i));
0873         iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
0874                     tc6393xb->scr + SCR_GPI_BCR(i));
0875     }
0876 
0877     return 0;
0878 }
0879 #else
0880 #define tc6393xb_suspend NULL
0881 #define tc6393xb_resume NULL
0882 #endif
0883 
0884 static struct platform_driver tc6393xb_driver = {
0885     .probe = tc6393xb_probe,
0886     .remove = tc6393xb_remove,
0887     .suspend = tc6393xb_suspend,
0888     .resume = tc6393xb_resume,
0889 
0890     .driver = {
0891         .name = "tc6393xb",
0892     },
0893 };
0894 
0895 static int __init tc6393xb_init(void)
0896 {
0897     return platform_driver_register(&tc6393xb_driver);
0898 }
0899 
0900 static void __exit tc6393xb_exit(void)
0901 {
0902     platform_driver_unregister(&tc6393xb_driver);
0903 }
0904 
0905 subsys_initcall(tc6393xb_init);
0906 module_exit(tc6393xb_exit);
0907 
0908 MODULE_LICENSE("GPL v2");
0909 MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
0910 MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
0911 MODULE_ALIAS("platform:tc6393xb");
0912