tc6393xb.c (24077B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Toshiba TC6393XB SoC support 4 * 5 * Copyright(c) 2005-2006 Chris Humbert 6 * Copyright(c) 2005 Dirk Opfer 7 * Copyright(c) 2005 Ian Molton <spyro@f2s.com> 8 * Copyright(c) 2007 Dmitry Baryshkov 9 * 10 * Based on code written by Sharp/Lineo for 2.4 kernels 11 * Based on locomo.c 12 */ 13 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/io.h> 17#include <linux/irq.h> 18#include <linux/platform_device.h> 19#include <linux/clk.h> 20#include <linux/err.h> 21#include <linux/mfd/core.h> 22#include <linux/mfd/tmio.h> 23#include <linux/mfd/tc6393xb.h> 24#include <linux/gpio/driver.h> 25#include <linux/gpio/machine.h> 26#include <linux/gpio/consumer.h> 27#include <linux/slab.h> 28 29#define SCR_REVID 0x08 /* b Revision ID */ 30#define SCR_ISR 0x50 /* b Interrupt Status */ 31#define SCR_IMR 0x52 /* b Interrupt Mask */ 32#define SCR_IRR 0x54 /* b Interrupt Routing */ 33#define SCR_GPER 0x60 /* w GP Enable */ 34#define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */ 35#define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */ 36#define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */ 37#define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */ 38#define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */ 39#define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */ 40#define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */ 41#define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */ 42#define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */ 43#define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */ 44#define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */ 45#define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */ 46#define SCR_CCR 0x98 /* w Clock Control */ 47#define SCR_PLL2CR 0x9a /* w PLL2 Control */ 48#define SCR_PLL1CR 0x9c /* l PLL1 Control */ 49#define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */ 50#define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */ 51#define SCR_FER 0xe0 /* b Function Enable */ 52#define SCR_MCR 0xe4 /* w Mode Control */ 53#define SCR_CONFIG 0xfc /* b Configuration Control */ 54#define SCR_DEBUG 0xff /* b Debug */ 55 56#define SCR_CCR_CK32K BIT(0) 57#define SCR_CCR_USBCK BIT(1) 58#define SCR_CCR_UNK1 BIT(4) 59#define SCR_CCR_MCLK_MASK (7 << 8) 60#define SCR_CCR_MCLK_OFF (0 << 8) 61#define SCR_CCR_MCLK_12 (1 << 8) 62#define SCR_CCR_MCLK_24 (2 << 8) 63#define SCR_CCR_MCLK_48 (3 << 8) 64#define SCR_CCR_HCLK_MASK (3 << 12) 65#define SCR_CCR_HCLK_24 (0 << 12) 66#define SCR_CCR_HCLK_48 (1 << 12) 67 68#define SCR_FER_USBEN BIT(0) /* USB host enable */ 69#define SCR_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */ 70#define SCR_FER_SLCDEN BIT(2) /* SLCD enable */ 71 72#define SCR_MCR_RDY_MASK (3 << 0) 73#define SCR_MCR_RDY_OPENDRAIN (0 << 0) 74#define SCR_MCR_RDY_TRISTATE (1 << 0) 75#define SCR_MCR_RDY_PUSHPULL (2 << 0) 76#define SCR_MCR_RDY_UNK BIT(2) 77#define SCR_MCR_RDY_EN BIT(3) 78#define SCR_MCR_INT_MASK (3 << 4) 79#define SCR_MCR_INT_OPENDRAIN (0 << 4) 80#define SCR_MCR_INT_TRISTATE (1 << 4) 81#define SCR_MCR_INT_PUSHPULL (2 << 4) 82#define SCR_MCR_INT_UNK BIT(6) 83#define SCR_MCR_INT_EN BIT(7) 84/* bits 8 - 16 are unknown */ 85 86#define TC_GPIO_BIT(i) (1 << (i & 0x7)) 87 88/*--------------------------------------------------------------------------*/ 89 90struct tc6393xb { 91 void __iomem *scr; 92 struct device *dev; 93 94 struct gpio_chip gpio; 95 struct gpio_desc *vcc_on; 96 97 struct clk *clk; /* 3,6 Mhz */ 98 99 raw_spinlock_t lock; /* protects RMW cycles */ 100 101 struct { 102 u8 fer; 103 u16 ccr; 104 u8 gpi_bcr[3]; 105 u8 gpo_dsr[3]; 106 u8 gpo_doecr[3]; 107 } suspend_state; 108 109 struct resource rscr; 110 struct resource *iomem; 111 int irq; 112 int irq_base; 113}; 114 115enum { 116 TC6393XB_CELL_NAND, 117 TC6393XB_CELL_MMC, 118 TC6393XB_CELL_OHCI, 119 TC6393XB_CELL_FB, 120}; 121 122/*--------------------------------------------------------------------------*/ 123 124static int tc6393xb_nand_enable(struct platform_device *nand) 125{ 126 struct tc6393xb *tc6393xb = dev_get_drvdata(nand->dev.parent); 127 unsigned long flags; 128 129 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 130 131 /* SMD buffer on */ 132 dev_dbg(nand->dev.parent, "SMD buffer on\n"); 133 tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); 134 135 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 136 137 return 0; 138} 139 140static const struct resource tc6393xb_nand_resources[] = { 141 { 142 .start = 0x1000, 143 .end = 0x1007, 144 .flags = IORESOURCE_MEM, 145 }, 146 { 147 .start = 0x0100, 148 .end = 0x01ff, 149 .flags = IORESOURCE_MEM, 150 }, 151 { 152 .start = IRQ_TC6393_NAND, 153 .end = IRQ_TC6393_NAND, 154 .flags = IORESOURCE_IRQ, 155 }, 156}; 157 158static const struct resource tc6393xb_mmc_resources[] = { 159 { 160 .start = 0x800, 161 .end = 0x9ff, 162 .flags = IORESOURCE_MEM, 163 }, 164 { 165 .start = IRQ_TC6393_MMC, 166 .end = IRQ_TC6393_MMC, 167 .flags = IORESOURCE_IRQ, 168 }, 169}; 170 171static const struct resource tc6393xb_ohci_resources[] = { 172 { 173 .start = 0x3000, 174 .end = 0x31ff, 175 .flags = IORESOURCE_MEM, 176 }, 177 { 178 .start = 0x0300, 179 .end = 0x03ff, 180 .flags = IORESOURCE_MEM, 181 }, 182 { 183 .start = 0x010000, 184 .end = 0x017fff, 185 .flags = IORESOURCE_MEM, 186 }, 187 { 188 .start = 0x018000, 189 .end = 0x01ffff, 190 .flags = IORESOURCE_MEM, 191 }, 192 { 193 .start = IRQ_TC6393_OHCI, 194 .end = IRQ_TC6393_OHCI, 195 .flags = IORESOURCE_IRQ, 196 }, 197}; 198 199static const struct resource tc6393xb_fb_resources[] = { 200 { 201 .start = 0x5000, 202 .end = 0x51ff, 203 .flags = IORESOURCE_MEM, 204 }, 205 { 206 .start = 0x0500, 207 .end = 0x05ff, 208 .flags = IORESOURCE_MEM, 209 }, 210 { 211 .start = 0x100000, 212 .end = 0x1fffff, 213 .flags = IORESOURCE_MEM, 214 }, 215 { 216 .start = IRQ_TC6393_FB, 217 .end = IRQ_TC6393_FB, 218 .flags = IORESOURCE_IRQ, 219 }, 220}; 221 222static int tc6393xb_ohci_enable(struct platform_device *dev) 223{ 224 struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); 225 unsigned long flags; 226 u16 ccr; 227 u8 fer; 228 229 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 230 231 ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); 232 ccr |= SCR_CCR_USBCK; 233 tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); 234 235 fer = tmio_ioread8(tc6393xb->scr + SCR_FER); 236 fer |= SCR_FER_USBEN; 237 tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); 238 239 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 240 241 return 0; 242} 243 244static int tc6393xb_ohci_disable(struct platform_device *dev) 245{ 246 struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); 247 unsigned long flags; 248 u16 ccr; 249 u8 fer; 250 251 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 252 253 fer = tmio_ioread8(tc6393xb->scr + SCR_FER); 254 fer &= ~SCR_FER_USBEN; 255 tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); 256 257 ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); 258 ccr &= ~SCR_CCR_USBCK; 259 tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); 260 261 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 262 263 return 0; 264} 265 266static int tc6393xb_ohci_suspend(struct platform_device *dev) 267{ 268 struct tc6393xb_platform_data *tcpd = dev_get_platdata(dev->dev.parent); 269 270 /* We can't properly store/restore OHCI state, so fail here */ 271 if (tcpd->resume_restore) 272 return -EBUSY; 273 274 return tc6393xb_ohci_disable(dev); 275} 276 277static int tc6393xb_fb_enable(struct platform_device *dev) 278{ 279 struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); 280 unsigned long flags; 281 u16 ccr; 282 283 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 284 285 ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); 286 ccr &= ~SCR_CCR_MCLK_MASK; 287 ccr |= SCR_CCR_MCLK_48; 288 tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); 289 290 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 291 292 return 0; 293} 294 295static int tc6393xb_fb_disable(struct platform_device *dev) 296{ 297 struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); 298 unsigned long flags; 299 u16 ccr; 300 301 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 302 303 ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); 304 ccr &= ~SCR_CCR_MCLK_MASK; 305 ccr |= SCR_CCR_MCLK_OFF; 306 tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); 307 308 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 309 310 return 0; 311} 312 313int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) 314{ 315 struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent); 316 u8 fer; 317 unsigned long flags; 318 319 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 320 321 fer = ioread8(tc6393xb->scr + SCR_FER); 322 if (on) 323 fer |= SCR_FER_SLCDEN; 324 else 325 fer &= ~SCR_FER_SLCDEN; 326 iowrite8(fer, tc6393xb->scr + SCR_FER); 327 328 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 329 330 return 0; 331} 332EXPORT_SYMBOL(tc6393xb_lcd_set_power); 333 334int tc6393xb_lcd_mode(struct platform_device *fb, 335 const struct fb_videomode *mode) { 336 struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent); 337 unsigned long flags; 338 339 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 340 341 iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0); 342 iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2); 343 344 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 345 346 return 0; 347} 348EXPORT_SYMBOL(tc6393xb_lcd_mode); 349 350static int tc6393xb_mmc_enable(struct platform_device *mmc) 351{ 352 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); 353 354 tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0, 355 tc6393xb_mmc_resources[0].start & 0xfffe); 356 357 return 0; 358} 359 360static int tc6393xb_mmc_resume(struct platform_device *mmc) 361{ 362 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); 363 364 tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0, 365 tc6393xb_mmc_resources[0].start & 0xfffe); 366 367 return 0; 368} 369 370static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state) 371{ 372 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); 373 374 tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state); 375} 376 377static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state) 378{ 379 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent); 380 381 tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state); 382} 383 384static struct tmio_mmc_data tc6393xb_mmc_data = { 385 .hclk = 24000000, 386 .set_pwr = tc6393xb_mmc_pwr, 387 .set_clk_div = tc6393xb_mmc_clk_div, 388}; 389 390static struct mfd_cell tc6393xb_cells[] = { 391 [TC6393XB_CELL_NAND] = { 392 .name = "tmio-nand", 393 .enable = tc6393xb_nand_enable, 394 .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), 395 .resources = tc6393xb_nand_resources, 396 }, 397 [TC6393XB_CELL_MMC] = { 398 .name = "tmio-mmc", 399 .enable = tc6393xb_mmc_enable, 400 .resume = tc6393xb_mmc_resume, 401 .platform_data = &tc6393xb_mmc_data, 402 .pdata_size = sizeof(tc6393xb_mmc_data), 403 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), 404 .resources = tc6393xb_mmc_resources, 405 }, 406 [TC6393XB_CELL_OHCI] = { 407 .name = "tmio-ohci", 408 .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), 409 .resources = tc6393xb_ohci_resources, 410 .enable = tc6393xb_ohci_enable, 411 .suspend = tc6393xb_ohci_suspend, 412 .resume = tc6393xb_ohci_enable, 413 .disable = tc6393xb_ohci_disable, 414 }, 415 [TC6393XB_CELL_FB] = { 416 .name = "tmio-fb", 417 .num_resources = ARRAY_SIZE(tc6393xb_fb_resources), 418 .resources = tc6393xb_fb_resources, 419 .enable = tc6393xb_fb_enable, 420 .suspend = tc6393xb_fb_disable, 421 .resume = tc6393xb_fb_enable, 422 .disable = tc6393xb_fb_disable, 423 }, 424}; 425 426/*--------------------------------------------------------------------------*/ 427 428static int tc6393xb_gpio_get(struct gpio_chip *chip, 429 unsigned offset) 430{ 431 struct tc6393xb *tc6393xb = gpiochip_get_data(chip); 432 433 /* XXX: does dsr also represent inputs? */ 434 return !!(tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) 435 & TC_GPIO_BIT(offset)); 436} 437 438static void __tc6393xb_gpio_set(struct gpio_chip *chip, 439 unsigned offset, int value) 440{ 441 struct tc6393xb *tc6393xb = gpiochip_get_data(chip); 442 u8 dsr; 443 444 dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); 445 if (value) 446 dsr |= TC_GPIO_BIT(offset); 447 else 448 dsr &= ~TC_GPIO_BIT(offset); 449 450 tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); 451} 452 453static void tc6393xb_gpio_set(struct gpio_chip *chip, 454 unsigned offset, int value) 455{ 456 struct tc6393xb *tc6393xb = gpiochip_get_data(chip); 457 unsigned long flags; 458 459 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 460 461 __tc6393xb_gpio_set(chip, offset, value); 462 463 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 464} 465 466static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, 467 unsigned offset) 468{ 469 struct tc6393xb *tc6393xb = gpiochip_get_data(chip); 470 unsigned long flags; 471 u8 doecr; 472 473 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 474 475 doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 476 doecr &= ~TC_GPIO_BIT(offset); 477 tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 478 479 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 480 481 return 0; 482} 483 484static int tc6393xb_gpio_direction_output(struct gpio_chip *chip, 485 unsigned offset, int value) 486{ 487 struct tc6393xb *tc6393xb = gpiochip_get_data(chip); 488 unsigned long flags; 489 u8 doecr; 490 491 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 492 493 __tc6393xb_gpio_set(chip, offset, value); 494 495 doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 496 doecr |= TC_GPIO_BIT(offset); 497 tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 498 499 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 500 501 return 0; 502} 503 504/* 505 * TC6393XB GPIOs as used on TOSA, are the only user of this chip. 506 * GPIOs 2, 5, 8 and 13 are not connected. 507 */ 508#define TOSA_GPIO_TG_ON 0 509#define TOSA_GPIO_L_MUTE 1 510#define TOSA_GPIO_BL_C20MA 3 511#define TOSA_GPIO_CARD_VCC_ON 4 512#define TOSA_GPIO_CHARGE_OFF 6 513#define TOSA_GPIO_CHARGE_OFF_JC 7 514#define TOSA_GPIO_BAT0_V_ON 9 515#define TOSA_GPIO_BAT1_V_ON 10 516#define TOSA_GPIO_BU_CHRG_ON 11 517#define TOSA_GPIO_BAT_SW_ON 12 518#define TOSA_GPIO_BAT0_TH_ON 14 519#define TOSA_GPIO_BAT1_TH_ON 15 520 521 522GPIO_LOOKUP_SINGLE(tosa_lcd_gpio_lookup, "spi2.0", "tc6393xb", 523 TOSA_GPIO_TG_ON, "tg #pwr", GPIO_ACTIVE_HIGH); 524 525GPIO_LOOKUP_SINGLE(tosa_lcd_bl_gpio_lookup, "i2c-tos-bl", "tc6393xb", 526 TOSA_GPIO_BL_C20MA, "backlight", GPIO_ACTIVE_HIGH); 527 528GPIO_LOOKUP_SINGLE(tosa_audio_gpio_lookup, "tosa-audio", "tc6393xb", 529 TOSA_GPIO_L_MUTE, NULL, GPIO_ACTIVE_HIGH); 530 531static struct gpiod_lookup_table tosa_battery_gpio_lookup = { 532 .dev_id = "wm97xx-battery", 533 .table = { 534 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF, 535 "main charge off", GPIO_ACTIVE_HIGH), 536 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC, 537 "jacket charge off", GPIO_ACTIVE_HIGH), 538 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_V_ON, 539 "main battery", GPIO_ACTIVE_HIGH), 540 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_V_ON, 541 "jacket battery", GPIO_ACTIVE_HIGH), 542 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BU_CHRG_ON, 543 "backup battery", GPIO_ACTIVE_HIGH), 544 /* BAT1 and BAT0 thermistors appear to be swapped */ 545 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON, 546 "main battery temp", GPIO_ACTIVE_HIGH), 547 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_TH_ON, 548 "jacket battery temp", GPIO_ACTIVE_HIGH), 549 GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT_SW_ON, 550 "battery switch", GPIO_ACTIVE_HIGH), 551 { }, 552 }, 553}; 554 555static struct gpiod_lookup_table *tc6393xb_gpio_lookups[] = { 556 &tosa_lcd_gpio_lookup, 557 &tosa_lcd_bl_gpio_lookup, 558 &tosa_audio_gpio_lookup, 559 &tosa_battery_gpio_lookup, 560}; 561 562static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb) 563{ 564 struct gpio_chip *gc = &tc6393xb->gpio; 565 struct device *dev = tc6393xb->dev; 566 int ret; 567 568 gc->label = "tc6393xb"; 569 gc->base = -1; /* Dynamic allocation */ 570 gc->ngpio = 16; 571 gc->set = tc6393xb_gpio_set; 572 gc->get = tc6393xb_gpio_get; 573 gc->direction_input = tc6393xb_gpio_direction_input; 574 gc->direction_output = tc6393xb_gpio_direction_output; 575 576 ret = devm_gpiochip_add_data(dev, gc, tc6393xb); 577 if (ret) 578 return dev_err_probe(dev, ret, "failed to add GPIO chip\n"); 579 580 /* Register descriptor look-ups for consumers */ 581 gpiod_add_lookup_tables(tc6393xb_gpio_lookups, ARRAY_SIZE(tc6393xb_gpio_lookups)); 582 583 /* Request some of our own GPIOs */ 584 tc6393xb->vcc_on = gpiochip_request_own_desc(gc, TOSA_GPIO_CARD_VCC_ON, "VCC ON", 585 GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); 586 if (IS_ERR(tc6393xb->vcc_on)) 587 return dev_err_probe(dev, PTR_ERR(tc6393xb->vcc_on), 588 "failed to request VCC ON GPIO\n"); 589 590 return 0; 591} 592 593/*--------------------------------------------------------------------------*/ 594 595static void tc6393xb_irq(struct irq_desc *desc) 596{ 597 struct tc6393xb *tc6393xb = irq_desc_get_handler_data(desc); 598 unsigned int isr; 599 unsigned int i, irq_base; 600 601 irq_base = tc6393xb->irq_base; 602 603 while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) & 604 ~tmio_ioread8(tc6393xb->scr + SCR_IMR))) 605 for (i = 0; i < TC6393XB_NR_IRQS; i++) { 606 if (isr & (1 << i)) 607 generic_handle_irq(irq_base + i); 608 } 609} 610 611static void tc6393xb_irq_ack(struct irq_data *data) 612{ 613} 614 615static void tc6393xb_irq_mask(struct irq_data *data) 616{ 617 struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); 618 unsigned long flags; 619 u8 imr; 620 621 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 622 imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); 623 imr |= 1 << (data->irq - tc6393xb->irq_base); 624 tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); 625 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 626} 627 628static void tc6393xb_irq_unmask(struct irq_data *data) 629{ 630 struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); 631 unsigned long flags; 632 u8 imr; 633 634 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 635 imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); 636 imr &= ~(1 << (data->irq - tc6393xb->irq_base)); 637 tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); 638 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 639} 640 641static struct irq_chip tc6393xb_chip = { 642 .name = "tc6393xb", 643 .irq_ack = tc6393xb_irq_ack, 644 .irq_mask = tc6393xb_irq_mask, 645 .irq_unmask = tc6393xb_irq_unmask, 646}; 647 648static void tc6393xb_attach_irq(struct platform_device *dev) 649{ 650 struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 651 unsigned int irq, irq_base; 652 653 irq_base = tc6393xb->irq_base; 654 655 for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { 656 irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq); 657 irq_set_chip_data(irq, tc6393xb); 658 irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); 659 } 660 661 irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); 662 irq_set_chained_handler_and_data(tc6393xb->irq, tc6393xb_irq, 663 tc6393xb); 664} 665 666static void tc6393xb_detach_irq(struct platform_device *dev) 667{ 668 struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 669 unsigned int irq, irq_base; 670 671 irq_set_chained_handler_and_data(tc6393xb->irq, NULL, NULL); 672 673 irq_base = tc6393xb->irq_base; 674 675 for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) { 676 irq_set_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); 677 irq_set_chip(irq, NULL); 678 irq_set_chip_data(irq, NULL); 679 } 680} 681 682/*--------------------------------------------------------------------------*/ 683 684static int tc6393xb_probe(struct platform_device *dev) 685{ 686 struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); 687 struct tc6393xb *tc6393xb; 688 struct resource *iomem, *rscr; 689 int ret; 690 691 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); 692 if (!iomem) 693 return -EINVAL; 694 695 tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); 696 if (!tc6393xb) { 697 ret = -ENOMEM; 698 goto err_kzalloc; 699 } 700 tc6393xb->dev = &dev->dev; 701 702 raw_spin_lock_init(&tc6393xb->lock); 703 704 platform_set_drvdata(dev, tc6393xb); 705 706 ret = platform_get_irq(dev, 0); 707 if (ret >= 0) 708 tc6393xb->irq = ret; 709 else 710 goto err_noirq; 711 712 tc6393xb->iomem = iomem; 713 tc6393xb->irq_base = tcpd->irq_base; 714 715 tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI"); 716 if (IS_ERR(tc6393xb->clk)) { 717 ret = PTR_ERR(tc6393xb->clk); 718 goto err_clk_get; 719 } 720 721 rscr = &tc6393xb->rscr; 722 rscr->name = "tc6393xb-core"; 723 rscr->start = iomem->start; 724 rscr->end = iomem->start + 0xff; 725 rscr->flags = IORESOURCE_MEM; 726 727 ret = request_resource(iomem, rscr); 728 if (ret) 729 goto err_request_scr; 730 731 tc6393xb->scr = ioremap(rscr->start, resource_size(rscr)); 732 if (!tc6393xb->scr) { 733 ret = -ENOMEM; 734 goto err_ioremap; 735 } 736 737 ret = clk_prepare_enable(tc6393xb->clk); 738 if (ret) 739 goto err_clk_enable; 740 741 ret = tcpd->enable(dev); 742 if (ret) 743 goto err_enable; 744 745 iowrite8(0, tc6393xb->scr + SCR_FER); 746 iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); 747 iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48, 748 tc6393xb->scr + SCR_CCR); 749 iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | 750 SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | 751 BIT(15), tc6393xb->scr + SCR_MCR); 752 iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); 753 iowrite8(0, tc6393xb->scr + SCR_IRR); 754 iowrite8(0xbf, tc6393xb->scr + SCR_IMR); 755 756 printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", 757 tmio_ioread8(tc6393xb->scr + SCR_REVID), 758 (unsigned long) iomem->start, tc6393xb->irq); 759 760 ret = tc6393xb_register_gpio(tc6393xb); 761 if (ret) 762 goto err_gpio_add; 763 764 tc6393xb_attach_irq(dev); 765 766 tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data; 767 tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size = 768 sizeof(*tcpd->nand_data); 769 tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data; 770 tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); 771 772 ret = mfd_add_devices(&dev->dev, dev->id, 773 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), 774 iomem, tcpd->irq_base, NULL); 775 776 if (!ret) 777 return 0; 778 779 tc6393xb_detach_irq(dev); 780err_gpio_add: 781 tcpd->disable(dev); 782err_enable: 783 clk_disable_unprepare(tc6393xb->clk); 784err_clk_enable: 785 iounmap(tc6393xb->scr); 786err_ioremap: 787 release_resource(&tc6393xb->rscr); 788err_request_scr: 789 clk_put(tc6393xb->clk); 790err_noirq: 791err_clk_get: 792 kfree(tc6393xb); 793err_kzalloc: 794 return ret; 795} 796 797static int tc6393xb_remove(struct platform_device *dev) 798{ 799 struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); 800 struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 801 int ret; 802 803 mfd_remove_devices(&dev->dev); 804 805 tc6393xb_detach_irq(dev); 806 807 ret = tcpd->disable(dev); 808 clk_disable_unprepare(tc6393xb->clk); 809 iounmap(tc6393xb->scr); 810 release_resource(&tc6393xb->rscr); 811 clk_put(tc6393xb->clk); 812 kfree(tc6393xb); 813 814 return ret; 815} 816 817#ifdef CONFIG_PM 818static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) 819{ 820 struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); 821 struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 822 int i, ret; 823 824 tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); 825 tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); 826 827 for (i = 0; i < 3; i++) { 828 tc6393xb->suspend_state.gpo_dsr[i] = 829 ioread8(tc6393xb->scr + SCR_GPO_DSR(i)); 830 tc6393xb->suspend_state.gpo_doecr[i] = 831 ioread8(tc6393xb->scr + SCR_GPO_DOECR(i)); 832 tc6393xb->suspend_state.gpi_bcr[i] = 833 ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); 834 } 835 ret = tcpd->suspend(dev); 836 clk_disable_unprepare(tc6393xb->clk); 837 838 return ret; 839} 840 841static int tc6393xb_resume(struct platform_device *dev) 842{ 843 struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev); 844 struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 845 int ret; 846 int i; 847 848 ret = clk_prepare_enable(tc6393xb->clk); 849 if (ret) 850 return ret; 851 852 ret = tcpd->resume(dev); 853 if (ret) 854 return ret; 855 856 if (!tcpd->resume_restore) 857 return 0; 858 859 iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); 860 iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); 861 iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); 862 iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | 863 SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | 864 BIT(15), tc6393xb->scr + SCR_MCR); 865 iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); 866 iowrite8(0, tc6393xb->scr + SCR_IRR); 867 iowrite8(0xbf, tc6393xb->scr + SCR_IMR); 868 869 for (i = 0; i < 3; i++) { 870 iowrite8(tc6393xb->suspend_state.gpo_dsr[i], 871 tc6393xb->scr + SCR_GPO_DSR(i)); 872 iowrite8(tc6393xb->suspend_state.gpo_doecr[i], 873 tc6393xb->scr + SCR_GPO_DOECR(i)); 874 iowrite8(tc6393xb->suspend_state.gpi_bcr[i], 875 tc6393xb->scr + SCR_GPI_BCR(i)); 876 } 877 878 return 0; 879} 880#else 881#define tc6393xb_suspend NULL 882#define tc6393xb_resume NULL 883#endif 884 885static struct platform_driver tc6393xb_driver = { 886 .probe = tc6393xb_probe, 887 .remove = tc6393xb_remove, 888 .suspend = tc6393xb_suspend, 889 .resume = tc6393xb_resume, 890 891 .driver = { 892 .name = "tc6393xb", 893 }, 894}; 895 896static int __init tc6393xb_init(void) 897{ 898 return platform_driver_register(&tc6393xb_driver); 899} 900 901static void __exit tc6393xb_exit(void) 902{ 903 platform_driver_unregister(&tc6393xb_driver); 904} 905 906subsys_initcall(tc6393xb_init); 907module_exit(tc6393xb_exit); 908 909MODULE_LICENSE("GPL v2"); 910MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); 911MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); 912MODULE_ALIAS("platform:tc6393xb"); 913