17 #include <linux/kernel.h>
18 #include <linux/module.h>
28 #include <linux/slab.h>
30 #define SCR_REVID 0x08
35 #define SCR_GPI_SR(i) (0x64 + (i))
36 #define SCR_GPI_IMR(i) (0x68 + (i))
37 #define SCR_GPI_EDER(i) (0x6c + (i))
38 #define SCR_GPI_LIR(i) (0x70 + (i))
39 #define SCR_GPO_DSR(i) (0x78 + (i))
40 #define SCR_GPO_DOECR(i) (0x7c + (i))
41 #define SCR_GP_IARCR(i) (0x80 + (i))
42 #define SCR_GP_IARLCR(i) (0x84 + (i))
43 #define SCR_GPI_BCR(i) (0x88 + (i))
44 #define SCR_GPA_IARCR 0x8c
45 #define SCR_GPA_IARLCR 0x90
46 #define SCR_GPA_BCR 0x94
48 #define SCR_PLL2CR 0x9a
49 #define SCR_PLL1CR 0x9c
50 #define SCR_DIARCR 0xa0
51 #define SCR_DBOCR 0xa1
54 #define SCR_CONFIG 0xfc
55 #define SCR_DEBUG 0xff
57 #define SCR_CCR_CK32K BIT(0)
58 #define SCR_CCR_USBCK BIT(1)
59 #define SCR_CCR_UNK1 BIT(4)
60 #define SCR_CCR_MCLK_MASK (7 << 8)
61 #define SCR_CCR_MCLK_OFF (0 << 8)
62 #define SCR_CCR_MCLK_12 (1 << 8)
63 #define SCR_CCR_MCLK_24 (2 << 8)
64 #define SCR_CCR_MCLK_48 (3 << 8)
65 #define SCR_CCR_HCLK_MASK (3 << 12)
66 #define SCR_CCR_HCLK_24 (0 << 12)
67 #define SCR_CCR_HCLK_48 (1 << 12)
69 #define SCR_FER_USBEN BIT(0)
70 #define SCR_FER_LCDCVEN BIT(1)
71 #define SCR_FER_SLCDEN BIT(2)
73 #define SCR_MCR_RDY_MASK (3 << 0)
74 #define SCR_MCR_RDY_OPENDRAIN (0 << 0)
75 #define SCR_MCR_RDY_TRISTATE (1 << 0)
76 #define SCR_MCR_RDY_PUSHPULL (2 << 0)
77 #define SCR_MCR_RDY_UNK BIT(2)
78 #define SCR_MCR_RDY_EN BIT(3)
79 #define SCR_MCR_INT_MASK (3 << 4)
80 #define SCR_MCR_INT_OPENDRAIN (0 << 4)
81 #define SCR_MCR_INT_TRISTATE (1 << 4)
82 #define SCR_MCR_INT_PUSHPULL (2 << 4)
83 #define SCR_MCR_INT_UNK BIT(6)
84 #define SCR_MCR_INT_EN BIT(7)
87 #define TC_GPIO_BIT(i) (1 << (i & 0x7))
135 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
158 static struct resource tc6393xb_mmc_resources[] = {
171 static const struct resource tc6393xb_ohci_resources[] = {
239 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
261 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
279 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
297 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
318 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
335 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
347 tc6393xb_mmc_resources[0].
start & 0xfffe);
358 tc6393xb_mmc_resources[0].
start & 0xfffe);
381 .set_pwr = tc6393xb_mmc_pwr,
382 .set_clk_div = tc6393xb_mmc_clk_div,
388 .enable = tc6393xb_nand_enable,
389 .num_resources =
ARRAY_SIZE(tc6393xb_nand_resources),
390 .resources = tc6393xb_nand_resources,
394 .enable = tc6393xb_mmc_enable,
395 .resume = tc6393xb_mmc_resume,
396 .platform_data = &tc6393xb_mmc_data,
397 .pdata_size =
sizeof(tc6393xb_mmc_data),
399 .resources = tc6393xb_mmc_resources,
403 .num_resources =
ARRAY_SIZE(tc6393xb_ohci_resources),
404 .resources = tc6393xb_ohci_resources,
405 .enable = tc6393xb_ohci_enable,
406 .suspend = tc6393xb_ohci_disable,
407 .resume = tc6393xb_ohci_enable,
408 .disable = tc6393xb_ohci_disable,
412 .num_resources =
ARRAY_SIZE(tc6393xb_fb_resources),
413 .resources = tc6393xb_fb_resources,
414 .enable = tc6393xb_fb_enable,
415 .suspend = tc6393xb_fb_disable,
416 .resume = tc6393xb_fb_enable,
417 .disable = tc6393xb_fb_disable,
423 static int tc6393xb_gpio_get(
struct gpio_chip *
chip,
433 static void __tc6393xb_gpio_set(
struct gpio_chip *chip,
434 unsigned offset,
int value)
448 static void tc6393xb_gpio_set(
struct gpio_chip *chip,
449 unsigned offset,
int value)
456 __tc6393xb_gpio_set(chip, offset, value);
458 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
461 static int tc6393xb_gpio_direction_input(
struct gpio_chip *chip,
474 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
479 static int tc6393xb_gpio_direction_output(
struct gpio_chip *chip,
480 unsigned offset,
int value)
488 __tc6393xb_gpio_set(chip, offset, value);
494 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
499 static int tc6393xb_register_gpio(
struct tc6393xb *tc6393xb,
int gpio_base)
501 tc6393xb->
gpio.label =
"tc6393xb";
503 tc6393xb->
gpio.ngpio = 16;
504 tc6393xb->
gpio.set = tc6393xb_gpio_set;
505 tc6393xb->
gpio.get = tc6393xb_gpio_get;
506 tc6393xb->
gpio.direction_input = tc6393xb_gpio_direction_input;
507 tc6393xb->
gpio.direction_output = tc6393xb_gpio_direction_output;
517 struct tc6393xb *tc6393xb = irq_get_handler_data(irq);
537 struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
545 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
550 struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
558 spin_unlock_irqrestore(&tc6393xb->
lock, flags);
561 static struct irq_chip tc6393xb_chip = {
563 .irq_ack = tc6393xb_irq_ack,
564 .irq_mask = tc6393xb_irq_mask,
565 .irq_unmask = tc6393xb_irq_unmask,
570 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
583 irq_set_chained_handler(tc6393xb->
irq, tc6393xb_irq);
588 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
591 irq_set_chained_handler(tc6393xb->
irq,
NULL);
608 struct tc6393xb *tc6393xb;
616 tc6393xb = kzalloc(
sizeof *tc6393xb,
GFP_KERNEL);
624 platform_set_drvdata(dev, tc6393xb);
632 tc6393xb->
iomem = iomem;
636 if (IS_ERR(tc6393xb->
clk)) {
637 ret = PTR_ERR(tc6393xb->
clk);
641 rscr = &tc6393xb->
rscr;
642 rscr->
name =
"tc6393xb-core";
649 goto err_request_scr;
652 if (!tc6393xb->
scr) {
678 (
unsigned long) iomem->
start, tc6393xb->
irq);
680 tc6393xb->
gpio.base = -1;
683 ret = tc6393xb_register_gpio(tc6393xb, tcpd->
gpio_base);
688 tc6393xb_attach_irq(dev);
691 ret = tcpd->
setup(dev);
713 tc6393xb_detach_irq(dev);
716 if (tc6393xb->
gpio.base != -1)
737 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
745 tc6393xb_detach_irq(dev);
747 if (tc6393xb->
gpio.base != -1) {
750 dev_err(&dev->
dev,
"Can't remove gpio chip: %d\n", ret);
759 platform_set_drvdata(dev,
NULL);
770 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
776 for (i = 0; i < 3; i++) {
793 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
816 for (i = 0; i < 3; i++) {
828 #define tc6393xb_suspend NULL
829 #define tc6393xb_resume NULL
833 .probe = tc6393xb_probe,
844 static int __init tc6393xb_init(
void)
849 static void __exit tc6393xb_exit(
void)
858 MODULE_AUTHOR(
"Ian Molton, Dmitry Baryshkov and Dirk Opfer");