4 * Support functions for Retu ASIC
6 * Copyright (C) 2004, 2005 Nokia Corporation
8 * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
9 * David Weinehall <david.weinehall@nokia.com>, and
10 * Mikko Ylinen <mikko.k.ylinen@nokia.com>
12 * This file is subject to the terms and conditions of the GNU General
13 * Public License. See the file "COPYING" in the main directory of this
14 * archive for more details.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/module.h>
27 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/errno.h>
31 #include <linux/device.h>
32 #include <linux/miscdevice.h>
33 #include <linux/poll.h>
35 #include <linux/irq.h>
36 #include <linux/interrupt.h>
37 #include <linux/platform_device.h>
39 #include <asm/uaccess.h>
41 #include <asm/arch/mux.h>
42 #include <asm/arch/gpio.h>
43 #include <asm/arch/board.h>
51 static int retu_initialized;
52 static int retu_irq_pin;
53 static int retu_is_vilma;
55 static struct tasklet_struct retu_tasklet;
56 spinlock_t retu_lock = SPIN_LOCK_UNLOCKED;
58 static struct completion device_release;
60 struct retu_irq_handler_desc {
61 int (*func)(unsigned long);
66 static struct retu_irq_handler_desc retu_irq_handlers[MAX_RETU_IRQ_HANDLERS];
69 * retu_read_reg - Read a value from a register in Retu
70 * @reg: the register to read from
72 * This function returns the contents of the specified register
74 int retu_read_reg(int reg)
76 BUG_ON(!retu_initialized);
77 return cbus_read_reg(cbus_host, RETU_ID, reg);
81 * retu_write_reg - Write a value to a register in Retu
82 * @reg: the register to write to
83 * @reg: the value to write to the register
85 * This function writes a value to the specified register
87 void retu_write_reg(int reg, u16 val)
89 BUG_ON(!retu_initialized);
90 cbus_write_reg(cbus_host, RETU_ID, reg, val);
93 void retu_set_clear_reg_bits(int reg, u16 set, u16 clear)
98 spin_lock_irqsave(&retu_lock, flags);
99 w = retu_read_reg(reg);
102 retu_write_reg(reg, w);
103 spin_unlock_irqrestore(&retu_lock, flags);
106 #define ADC_MAX_CHAN_NUMBER 13
108 int retu_read_adc(int channel)
113 if (channel < 0 || channel > ADC_MAX_CHAN_NUMBER)
116 spin_lock_irqsave(&retu_lock, flags);
118 if ((channel == 8) && retu_is_vilma) {
119 int scr = retu_read_reg(RETU_REG_ADCSCR);
120 int ch = (retu_read_reg(RETU_REG_ADCR) >> 10) & 0xf;
121 if (((scr & 0xff) != 0) && (ch != 8))
122 retu_write_reg (RETU_REG_ADCSCR, (scr & ~0xff));
125 /* Select the channel and read result */
126 retu_write_reg(RETU_REG_ADCR, channel << 10);
127 res = retu_read_reg(RETU_REG_ADCR) & 0x3ff;
130 retu_write_reg(RETU_REG_ADCR, (1 << 13));
133 spin_unlock_irqrestore(&retu_lock, flags);
139 static u16 retu_disable_bogus_irqs(u16 mask)
143 for (i = 0; i < MAX_RETU_IRQ_HANDLERS; i++) {
146 if (retu_irq_handlers[i].func != NULL)
148 /* an IRQ was enabled but we don't have a handler for it */
149 printk(KERN_INFO PFX "disabling bogus IRQ %d\n", i);
156 * Disable given RETU interrupt
158 void retu_disable_irq(int id)
163 spin_lock_irqsave(&retu_lock, flags);
164 mask = retu_read_reg(RETU_REG_IMR);
166 mask = retu_disable_bogus_irqs(mask);
167 retu_write_reg(RETU_REG_IMR, mask);
168 spin_unlock_irqrestore(&retu_lock, flags);
172 * Enable given RETU interrupt
174 void retu_enable_irq(int id)
180 printk("Enabling Retu IRQ %d\n", id);
183 spin_lock_irqsave(&retu_lock, flags);
184 mask = retu_read_reg(RETU_REG_IMR);
186 mask = retu_disable_bogus_irqs(mask);
187 retu_write_reg(RETU_REG_IMR, mask);
188 spin_unlock_irqrestore(&retu_lock, flags);
192 * Acknowledge given RETU interrupt
194 void retu_ack_irq(int id)
196 retu_write_reg(RETU_REG_IDR, 1 << id);
200 * RETU interrupt handler. Only schedules the tasklet.
202 static irqreturn_t retu_irq_handler(int irq, void *dev_id)
204 tasklet_schedule(&retu_tasklet);
211 static void retu_tasklet_handler(unsigned long data)
213 struct retu_irq_handler_desc *hnd;
219 id = retu_read_reg(RETU_REG_IDR);
220 im = ~retu_read_reg(RETU_REG_IMR);
226 for (i = 0; id != 0; i++, id >>= 1) {
229 hnd = &retu_irq_handlers[i];
230 if (hnd->func == NULL) {
231 /* Spurious retu interrupt - disable and ack it */
232 printk(KERN_INFO "Spurious Retu interrupt "
240 * Don't acknowledge the interrupt here
241 * It must be done explicitly
248 * Register the handler for a given RETU interrupt source.
250 int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
252 struct retu_irq_handler_desc *hnd;
254 if (irq_handler == NULL || id >= MAX_RETU_IRQ_HANDLERS ||
256 printk(KERN_ERR PFX "Invalid arguments to %s\n",
260 hnd = &retu_irq_handlers[id];
261 if (hnd->func != NULL) {
262 printk(KERN_ERR PFX "IRQ %d already reserved\n", id);
265 printk(KERN_INFO PFX "Registering interrupt %d for device %s\n",
267 hnd->func = irq_handler;
269 strlcpy(hnd->name, name, sizeof(hnd->name));
278 * Unregister the handler for a given RETU interrupt source.
280 void retu_free_irq(int id)
282 struct retu_irq_handler_desc *hnd;
284 if (id >= MAX_RETU_IRQ_HANDLERS) {
285 printk(KERN_ERR PFX "Invalid argument to %s\n",
289 hnd = &retu_irq_handlers[id];
290 if (hnd->func == NULL) {
291 printk(KERN_ERR PFX "IRQ %d already freed\n", id);
295 retu_disable_irq(id);
300 * retu_power_off - Shut down power to system
302 * This function puts the system in power off state
304 static void retu_power_off(void)
306 /* Ignore power button state */
307 retu_write_reg(RETU_REG_CC1, retu_read_reg(RETU_REG_CC1) | 2);
308 /* Expire watchdog immediately */
309 retu_write_reg(RETU_REG_WATCHDOG, 0);
310 /* Wait for poweroff*/
315 * retu_probe - Probe for Retu ASIC
316 * @dev: the Retu device
318 * Probe for the Retu ASIC and allocate memory
319 * for its device-struct if found
321 static int __devinit retu_probe(struct device *dev)
323 const struct omap_em_asic_bb5_config * em_asic_config;
326 /* Prepare tasklet */
327 tasklet_init(&retu_tasklet, retu_tasklet_handler, 0);
329 em_asic_config = omap_get_config(OMAP_TAG_EM_ASIC_BB5,
330 struct omap_em_asic_bb5_config);
331 if (em_asic_config == NULL) {
332 printk(KERN_ERR PFX "Unable to retrieve config data\n");
336 retu_irq_pin = em_asic_config->retu_irq_gpio;
338 if ((ret = omap_request_gpio(retu_irq_pin)) < 0) {
339 printk(KERN_ERR PFX "Unable to reserve IRQ GPIO\n");
343 /* Set the pin as input */
344 omap_set_gpio_direction(retu_irq_pin, 1);
346 /* Rising edge triggers the IRQ */
347 set_irq_type(OMAP_GPIO_IRQ(retu_irq_pin), IRQ_TYPE_EDGE_RISING);
349 retu_initialized = 1;
351 rev = retu_read_reg(RETU_REG_ASICR) & 0xff;
355 printk(KERN_INFO "%s v%d.%d found\n", retu_is_vilma ? "Vilma" : "Retu",
356 (rev >> 4) & 0x07, rev & 0x0f);
358 /* Mask all RETU interrupts */
359 retu_write_reg(RETU_REG_IMR, 0xffff);
361 ret = request_irq(OMAP_GPIO_IRQ(retu_irq_pin), retu_irq_handler, 0,
364 printk(KERN_ERR PFX "Unable to register IRQ handler\n");
365 omap_free_gpio(retu_irq_pin);
368 set_irq_wake(OMAP_GPIO_IRQ(retu_irq_pin), 1);
370 /* Register power off function */
371 pm_power_off = retu_power_off;
373 #ifdef CONFIG_CBUS_RETU_USER
374 /* Initialize user-space interface */
375 if (retu_user_init() < 0) {
376 printk(KERN_ERR "Unable to initialize driver\n");
377 free_irq(OMAP_GPIO_IRQ(retu_irq_pin), 0);
378 omap_free_gpio(retu_irq_pin);
386 static int retu_remove(struct device *dev)
388 #ifdef CONFIG_CBUS_RETU_USER
391 /* Mask all RETU interrupts */
392 retu_write_reg(RETU_REG_IMR, 0xffff);
393 free_irq(OMAP_GPIO_IRQ(retu_irq_pin), 0);
394 omap_free_gpio(retu_irq_pin);
395 tasklet_kill(&retu_tasklet);
400 static void retu_device_release(struct device *dev)
402 complete(&device_release);
405 static struct device_driver retu_driver = {
407 .bus = &platform_bus_type,
409 .remove = retu_remove,
412 static struct platform_device retu_device = {
416 .release = retu_device_release,
421 * retu_init - initialise Retu driver
423 * Initialise the Retu driver and return 0 if everything worked ok
425 static int __init retu_init(void)
429 printk(KERN_INFO "Retu/Vilma driver initialising\n");
431 init_completion(&device_release);
433 if ((ret = driver_register(&retu_driver)) < 0)
436 if ((ret = platform_device_register(&retu_device)) < 0) {
437 driver_unregister(&retu_driver);
446 static void __exit retu_exit(void)
448 platform_device_unregister(&retu_device);
449 driver_unregister(&retu_driver);
450 wait_for_completion(&device_release);
453 EXPORT_SYMBOL(retu_request_irq);
454 EXPORT_SYMBOL(retu_free_irq);
455 EXPORT_SYMBOL(retu_enable_irq);
456 EXPORT_SYMBOL(retu_disable_irq);
457 EXPORT_SYMBOL(retu_ack_irq);
458 EXPORT_SYMBOL(retu_read_reg);
459 EXPORT_SYMBOL(retu_write_reg);
461 subsys_initcall(retu_init);
462 module_exit(retu_exit);
464 MODULE_DESCRIPTION("Retu ASIC control");
465 MODULE_LICENSE("GPL");
466 MODULE_AUTHOR("Juha Yrjölä, David Weinehall, and Mikko Ylinen");