2 * Atmel PIO2 Port Multiplexer support
4 * Copyright (C) 2004-2006 Atmel Corporation
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/clk.h>
12 #include <linux/debugfs.h>
14 #include <linux/platform_device.h>
18 #include <asm/arch/portmux.h>
22 #define MAX_NR_PIO_DEVICES 8
26 const struct platform_device
*pdev
;
32 static struct pio_device pio_dev
[MAX_NR_PIO_DEVICES
];
34 static struct pio_device
*gpio_to_pio(unsigned int gpio
)
36 struct pio_device
*pio
;
40 if (index
>= MAX_NR_PIO_DEVICES
)
42 pio
= &pio_dev
[index
];
49 /* Pin multiplexing API */
51 void __init
at32_select_periph(unsigned int pin
, unsigned int periph
,
54 struct pio_device
*pio
;
55 unsigned int pin_index
= pin
& 0x1f;
56 u32 mask
= 1 << pin_index
;
58 pio
= gpio_to_pio(pin
);
60 printk("pio: invalid pin %u\n", pin
);
64 if (unlikely(test_and_set_bit(pin_index
, &pio
->pinmux_mask
))) {
65 printk("%s: pin %u is busy\n", pio
->name
, pin_index
);
69 pio_writel(pio
, PUER
, mask
);
71 pio_writel(pio
, BSR
, mask
);
73 pio_writel(pio
, ASR
, mask
);
75 pio_writel(pio
, PDR
, mask
);
76 if (!(flags
& AT32_GPIOF_PULLUP
))
77 pio_writel(pio
, PUDR
, mask
);
85 void __init
at32_select_gpio(unsigned int pin
, unsigned long flags
)
87 struct pio_device
*pio
;
88 unsigned int pin_index
= pin
& 0x1f;
89 u32 mask
= 1 << pin_index
;
91 pio
= gpio_to_pio(pin
);
93 printk("pio: invalid pin %u\n", pin
);
97 if (unlikely(test_and_set_bit(pin_index
, &pio
->pinmux_mask
))) {
98 printk("%s: pin %u is busy\n", pio
->name
, pin_index
);
102 pio_writel(pio
, PUER
, mask
);
103 if (flags
& AT32_GPIOF_HIGH
)
104 pio_writel(pio
, SODR
, mask
);
106 pio_writel(pio
, CODR
, mask
);
107 if (flags
& AT32_GPIOF_OUTPUT
)
108 pio_writel(pio
, OER
, mask
);
110 pio_writel(pio
, ODR
, mask
);
112 pio_writel(pio
, PER
, mask
);
113 if (!(flags
& AT32_GPIOF_PULLUP
))
114 pio_writel(pio
, PUDR
, mask
);
122 static int __init
pio_probe(struct platform_device
*pdev
)
124 struct pio_device
*pio
= NULL
;
126 BUG_ON(pdev
->id
>= MAX_NR_PIO_DEVICES
);
127 pio
= &pio_dev
[pdev
->id
];
130 /* TODO: Interrupts */
132 platform_set_drvdata(pdev
, pio
);
134 printk(KERN_INFO
"%s: Atmel Port Multiplexer at 0x%p (irq %d)\n",
135 pio
->name
, pio
->regs
, platform_get_irq(pdev
, 0));
140 static struct platform_driver pio_driver
= {
147 static int __init
pio_init(void)
149 return platform_driver_register(&pio_driver
);
151 subsys_initcall(pio_init
);
153 void __init
at32_init_pio(struct platform_device
*pdev
)
155 struct resource
*regs
;
156 struct pio_device
*pio
;
158 if (pdev
->id
> MAX_NR_PIO_DEVICES
) {
159 dev_err(&pdev
->dev
, "only %d PIO devices supported\n",
164 pio
= &pio_dev
[pdev
->id
];
165 snprintf(pio
->name
, sizeof(pio
->name
), "pio%d", pdev
->id
);
167 regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
169 dev_err(&pdev
->dev
, "no mmio resource defined\n");
173 pio
->clk
= clk_get(&pdev
->dev
, "mck");
174 if (IS_ERR(pio
->clk
))
176 * This is a fatal error, but if we continue we might
177 * be so lucky that we manage to initialize the
178 * console and display this message...
180 dev_err(&pdev
->dev
, "no mck clock defined\n");
182 clk_enable(pio
->clk
);
185 pio
->regs
= ioremap(regs
->start
, regs
->end
- regs
->start
+ 1);
187 pio_writel(pio
, ODR
, ~0UL);
188 pio_writel(pio
, PER
, ~0UL);