sync hh.org
[hh.org.git] / drivers / soc / samcop_base.c
blobb531512bd8a342ec69b10e64b4827a3776d49bc5
1 /*
2 * Hardware definitions for HP iPAQ Handheld Computers
4 * Copyright 2000-2003 Hewlett-Packard Company.
5 * Copyright 2005 Phil Blundell
7 * Use consistent with the GNU GPL is permitted,
8 * provided that this copyright notice is
9 * preserved in its entirety in all copies and derived works.
11 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
12 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
13 * FITNESS FOR ANY PARTICULAR PURPOSE.
15 * Author: Jamey Hicks.
17 * History:
19 * 2002-08-23 Jamey Hicks GPIO and IRQ support for iPAQ H5400
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/kernel.h>
26 #include <linux/tty.h>
27 #include <linux/sched.h>
28 #include <linux/interrupt.h>
29 #include <linux/pm.h>
30 #include <linux/bootmem.h>
31 #include <linux/delay.h>
32 #include <linux/platform_device.h>
33 #include <linux/soc-old.h>
34 #include <linux/dma-mapping.h>
36 #include <asm/irq.h>
37 #include <asm/hardware.h>
38 #include <asm/setup.h>
39 #include <asm/io.h>
40 #include <asm/mach-types.h>
42 #include <asm/mach/irq.h>
43 #include <asm/mach/arch.h>
44 #include <asm/mach/map.h>
46 #include <linux/clk.h>
48 #include <asm/arch/pxa-regs.h>
49 #include <asm/arch/h5400-asic.h>
50 #include <asm/arch/h5400-gpio.h>
51 #include <asm/hardware/ipaq-samcop.h>
52 #include <asm/hardware/samcop_base.h>
53 #include <asm/hardware/samcop-sdi.h>
54 #include <asm/hardware/samcop-dma.h>
55 #include <asm/arch/pxa-dmabounce.h>
56 #include "../mmc/samcop_sdi.h"
58 #include <asm/arch/irq.h>
59 #include <asm/arch/clock.h>
60 #include <asm/types.h>
62 #include "../../arch/arm/common/ipaq/clock.h"
64 struct samcop_data
66 int irq_base, irq_nr;
67 void *mapping;
68 spinlock_t gpio_lock;
69 unsigned long irqmask;
70 struct platform_device **devices;
71 int ndevices;
74 static int samcop_remove (struct device *dev);
75 static int samcop_gclk (void *ptr);
76 static void samcop_set_gpio_a_pullup (struct device *dev, u32 mask, u32 bits);
77 static void
78 samcop_set_gpio_a_con (struct device *dev, unsigned int idx, u32 mask, u32 bits);
79 void
80 samcop_set_gpio_int (struct device *dev, unsigned int idx, u32 mask, u32 bits);
81 void
82 samcop_set_gpio_int_enable (struct device *dev, unsigned int idx, u32 mask, u32 bits);
83 void
84 samcop_set_gpio_filter_config (struct device *dev, unsigned int idx, u32 mask,
85 u32 bits);
87 /***********************************************************************************/
88 /* Register access */
89 /***********************************************************************************/
91 static inline void
92 samcop_write_register (struct samcop_data *samcop, unsigned long addr, unsigned long value)
94 __raw_writel (value, (unsigned long)samcop->mapping + addr);
97 static inline unsigned long
98 samcop_read_register (struct samcop_data *samcop, unsigned long addr)
100 return __raw_readl ((unsigned long)samcop->mapping + addr);
103 /***********************************************************************************/
104 /* ASIC IRQ demux */
105 /***********************************************************************************/
107 #define MAX_ASIC_ISR_LOOPS 1000
109 static void
110 samcop_irq_demux (unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
112 int i;
113 struct samcop_data *samcop;
114 u32 pending;
116 // Tell processor to acknowledge its interrupt
117 desc->chip->ack(irq);
118 samcop = desc->handler_data;
120 if (0) printk("%s: interrupt received\n", __FUNCTION__);
122 for ( i = 0 ; (i < MAX_ASIC_ISR_LOOPS); i++ ) {
123 int asic_irq;
125 pending = samcop_read_register (samcop, SAMCOP_IC_INTPND);
126 if (!pending)
127 break;
129 asic_irq = samcop->irq_base + (31 - __builtin_clz (pending));
130 desc = irq_desc + asic_irq;
131 desc->handle_irq(asic_irq, desc, regs);
134 if (i >= MAX_ASIC_ISR_LOOPS && pending) {
135 u32 val;
137 printk(KERN_WARNING
138 "%s: interrupt processing overrun, pending=0x%08x. "
139 "Masking interrupt\n", __FUNCTION__, pending);
140 val = samcop_read_register (samcop, SAMCOP_IC_INTMSK);
141 samcop_write_register (samcop, SAMCOP_IC_INTMSK, val | pending);
142 samcop_write_register (samcop, SAMCOP_IC_SRCPND, pending);
143 samcop_write_register (samcop, SAMCOP_IC_INTPND, pending);
147 /***********************************************************************************/
148 /* ASIC EPS IRQ demux */
149 /***********************************************************************************/
151 static u32 eps_irq_mask[] = {
152 SAMCOP_PCMCIA_EPS_CD0_N, /* IRQ_GPIO_SAMCOP_EPS_CD0 */
153 SAMCOP_PCMCIA_EPS_CD1_N, /* IRQ_GPIO_SAMCOP_EPS_CD1 */
154 SAMCOP_PCMCIA_EPS_IRQ0_N, /* IRQ_GPIO_SAMCOP_EPS_IRQ0 */
155 SAMCOP_PCMCIA_EPS_IRQ1_N, /* IRQ_GPIO_SAMCOP_EPS_IRQ1 */
156 (SAMCOP_PCMCIA_EPS_ODET0_N|SAMCOP_PCMCIA_EPS_ODET1_N),/* IRQ_GPIO_SAMCOP_EPS_ODET */
157 SAMCOP_PCMCIA_EPS_BATT_FLT/* IRQ_GPIO_SAMCOP_EPS_BATT_FAULT */
160 static void
161 samcop_asic_eps_irq_demux (unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
163 int i;
164 struct samcop_data *samcop;
165 u32 eps_pending;
167 samcop = desc->handler_data;
169 if (0) printk("%s: interrupt received irq=%d\n", __FUNCTION__, irq);
171 for ( i = 0 ; (i < MAX_ASIC_ISR_LOOPS) ; i++ ) {
172 int j;
173 eps_pending = samcop_read_register (samcop, SAMCOP_PCMCIA_IP);
174 if (!eps_pending)
175 break;
176 if (0) printk("%s: eps_pending=0x%08x\n", __FUNCTION__, eps_pending);
177 for ( j = 0 ; j < SAMCOP_EPS_IRQ_COUNT ; j++ )
178 if ( eps_pending & eps_irq_mask[j] ) {
179 int eps_irq = samcop->irq_base + j + SAMCOP_EPS_IRQ_START;
180 desc = irq_desc + eps_irq;
181 desc->handle_irq(eps_irq, desc, regs);
185 if (eps_pending)
186 printk("%s: interrupt processing overrun pending=0x%08x\n", __FUNCTION__, eps_pending);
189 /***********************************************************************************/
190 /* ASIC GPIO IRQ demux */
191 /***********************************************************************************/
193 static void
194 samcop_asic_gpio_irq_demux (unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
196 u32 pending;
197 struct samcop_data *samcop;
198 int loop;
200 samcop = desc->handler_data;
202 for (loop = 0; loop < MAX_ASIC_ISR_LOOPS; loop++)
204 int i;
205 pending = samcop_read_register (samcop, SAMCOP_GPIO_INTPND);
207 if (!pending)
208 break;
210 for (i = 0; i < SAMCOP_GPIO_IRQ_COUNT; i++) {
211 if (pending & (1 << i)) {
212 int gpio_irq = samcop->irq_base + i + SAMCOP_GPIO_IRQ_START;
213 desc = irq_desc + gpio_irq;
214 desc->handle_irq(gpio_irq, desc, regs);
219 if (pending)
220 printk ("%s: demux overrun, pending=%08x\n", __FUNCTION__, pending);
223 /***********************************************************************************/
224 /* IRQ handling */
225 /***********************************************************************************/
227 /* ack <- IRQ is first serviced.
228 mask <- IRQ is disabled.
229 unmask <- IRQ is enabled */
231 static void
232 samcop_asic_ack_ic_irq (unsigned int irq)
234 struct samcop_data *samcop = get_irq_chipdata (irq);
235 int mask = 1 << (irq - SAMCOP_IC_IRQ_START - samcop->irq_base);
237 samcop_write_register (samcop, SAMCOP_IC_SRCPND, mask);
238 samcop_write_register (samcop, SAMCOP_IC_INTPND, mask);
241 static void
242 samcop_asic_mask_ic_irq (unsigned int irq)
244 struct samcop_data *samcop = get_irq_chipdata (irq);
245 int mask = 1 << (irq - SAMCOP_IC_IRQ_START - samcop->irq_base);
246 u32 val;
248 val = samcop_read_register (samcop, SAMCOP_IC_INTMSK);
249 val |= mask;
250 samcop_write_register (samcop, SAMCOP_IC_INTMSK, val);
253 static void
254 samcop_asic_unmask_ic_irq (unsigned int irq)
256 struct samcop_data *samcop = get_irq_chipdata (irq);
257 int mask = 1 << (irq - SAMCOP_IC_IRQ_START - samcop->irq_base);
258 u32 val;
260 val = samcop_read_register (samcop, SAMCOP_IC_INTMSK);
261 val &= ~mask;
262 samcop_write_register (samcop, SAMCOP_IC_INTMSK, val);
265 static void
266 samcop_asic_ack_eps_irq (unsigned int irq)
268 struct samcop_data *samcop = get_irq_chipdata (irq);
269 int mask = eps_irq_mask[irq - SAMCOP_EPS_IRQ_START - samcop->irq_base];
271 samcop_write_register (samcop, SAMCOP_PCMCIA_IP, mask);
274 static void
275 samcop_asic_mask_eps_irq (unsigned int irq)
277 struct samcop_data *samcop = get_irq_chipdata (irq);
278 int mask = eps_irq_mask[irq - SAMCOP_EPS_IRQ_START - samcop->irq_base];
279 u32 val;
281 val = samcop_read_register (samcop, SAMCOP_PCMCIA_IC);
282 val &= ~mask;
283 samcop_write_register (samcop, SAMCOP_PCMCIA_IC, val);
286 static void
287 samcop_asic_unmask_eps_irq (unsigned int irq)
289 struct samcop_data *samcop = get_irq_chipdata (irq);
290 int mask = eps_irq_mask[irq - SAMCOP_EPS_IRQ_START - samcop->irq_base];
291 u32 val;
293 val = samcop_read_register (samcop, SAMCOP_PCMCIA_IC);
294 val |= mask;
295 samcop_write_register (samcop, SAMCOP_PCMCIA_IC, val);
298 static void
299 samcop_asic_ack_gpio_irq (unsigned int irq)
301 struct samcop_data *samcop = get_irq_chipdata (irq);
303 samcop_write_register (samcop, SAMCOP_GPIO_INTPND,
304 1 << (irq - SAMCOP_GPIO_IRQ_START - samcop->irq_base));
307 static void
308 samcop_asic_mask_gpio_irq (unsigned int irq)
310 struct samcop_data *samcop = get_irq_chipdata (irq);
311 u32 mask = 1 << (irq - SAMCOP_GPIO_IRQ_START - samcop->irq_base);
312 u32 val;
314 val = samcop_read_register (samcop, SAMCOP_GPIO_ENINT2);
315 val &= ~mask;
316 samcop_write_register (samcop, SAMCOP_GPIO_ENINT2, val);
319 static void
320 samcop_asic_unmask_gpio_irq (unsigned int irq)
322 struct samcop_data *samcop = get_irq_chipdata (irq);
323 u32 mask = 1 << (irq - SAMCOP_GPIO_IRQ_START - samcop->irq_base);
324 u32 val;
326 val = samcop_read_register (samcop, SAMCOP_GPIO_ENINT2);
327 val |= mask;
328 samcop_write_register (samcop, SAMCOP_GPIO_ENINT2, val);
331 static struct irqchip samcop_ic_irq_chip = {
332 .ack = samcop_asic_ack_ic_irq,
333 .mask = samcop_asic_mask_ic_irq,
334 .unmask = samcop_asic_unmask_ic_irq,
337 static struct irqchip samcop_eps_irq_chip = {
338 .ack = samcop_asic_ack_eps_irq,
339 .mask = samcop_asic_mask_eps_irq,
340 .unmask = samcop_asic_unmask_eps_irq,
343 static struct irqchip samcop_gpio_irq_chip = {
344 .ack = samcop_asic_ack_gpio_irq,
345 .mask = samcop_asic_mask_gpio_irq,
346 .unmask = samcop_asic_unmask_gpio_irq,
349 static void __init
350 samcop_irq_init (struct samcop_data *samcop)
352 int i;
354 /* mask all interrupts, this will cause the processor to ignore all interrupts from SAMCOP */
355 samcop_write_register (samcop, SAMCOP_IC_INTMSK, 0xffffffff);
357 /* clear out any pending irqs */
358 for (i = 0; i < 32; i++) {
359 if (samcop_read_register (samcop, SAMCOP_IC_INTPND) == 0) {
360 printk(KERN_INFO
361 "%s: no interrupts pending, looped %d %s. "
362 "Continuing\n", __FUNCTION__,
363 i + 1, ((i + 1) ? "time" : "times"));
364 break;
366 samcop_write_register (samcop, SAMCOP_IC_SRCPND, 0xffffffff);
367 samcop_write_register (samcop, SAMCOP_IC_INTPND, 0xffffffff);
370 samcop_write_register (samcop, SAMCOP_PCMCIA_IC, 0); /* nothing enabled */
371 samcop_write_register (samcop, SAMCOP_PCMCIA_IP, 0xff); /* clear anything here now */
372 samcop_write_register (samcop, SAMCOP_PCMCIA_IM, 0x2555);
374 samcop_write_register (samcop, SAMCOP_GPIO_ENINT1, 0);
375 samcop_write_register (samcop, SAMCOP_GPIO_ENINT2, 0);
376 samcop_write_register (samcop, SAMCOP_GPIO_INTPND, 0x3fff);
378 for (i = 0; i < SAMCOP_IC_IRQ_COUNT; i++) {
379 int irq = samcop->irq_base + i + SAMCOP_IC_IRQ_START;
380 set_irq_chipdata (irq, samcop);
381 set_irq_chip (irq, &samcop_ic_irq_chip);
382 set_irq_handler (irq, do_edge_IRQ);
383 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
386 for (i = 0; i < SAMCOP_EPS_IRQ_COUNT; i++) {
387 int irq = samcop->irq_base + i + SAMCOP_EPS_IRQ_START;
388 set_irq_chipdata (irq, samcop);
389 set_irq_chip (irq, &samcop_eps_irq_chip);
390 set_irq_handler (irq, do_edge_IRQ);
391 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
394 for (i = 0; i < SAMCOP_GPIO_IRQ_COUNT; i++) {
395 int irq = samcop->irq_base + i + SAMCOP_GPIO_IRQ_START;
396 set_irq_chipdata (irq, samcop);
397 set_irq_chip (irq, &samcop_gpio_irq_chip);
398 set_irq_handler (irq, do_edge_IRQ);
399 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
402 set_irq_data (samcop->irq_base + _IRQ_SAMCOP_PCMCIA, samcop);
403 set_irq_chained_handler (samcop->irq_base + _IRQ_SAMCOP_PCMCIA,
404 samcop_asic_eps_irq_demux);
405 set_irq_data (samcop->irq_base + _IRQ_SAMCOP_GPIO, samcop);
406 set_irq_chained_handler (samcop->irq_base + _IRQ_SAMCOP_GPIO,
407 samcop_asic_gpio_irq_demux);
409 set_irq_data (samcop->irq_nr, samcop);
410 set_irq_type (samcop->irq_nr, IRQT_FALLING);
411 set_irq_chained_handler (samcop->irq_nr, samcop_irq_demux);
414 /*************************************************************
415 * SAMCOP SD interface hooks and initialization
416 *************************************************************/
418 samcop_dma_needs_bounce (struct device *dev, dma_addr_t addr, size_t size)
420 return (addr + size >= H5400_SAMCOP_BASE + _SAMCOP_SRAM_Base + SAMCOP_SRAM_SIZE);
423 static u64 samcop_sdi_dmamask = 0xffffffffUL;
425 static void
426 samcop_sdi_init(struct device *dev)
428 struct samcop_data *samcop = dev->parent->driver_data;
429 struct samcop_sdi_data *plat = dev->platform_data;
431 /* Init run-time values */
432 plat->f_min = samcop_gclk(samcop) / 256; /* Divisor is SDIPRE max + 1 */
433 plat->f_max = samcop_gclk(samcop) / 2; /* Divisor is SDIPRE min + 1 */
434 plat->dma_devaddr = (void *) _SAMCOP_SDI_Base + SAMCOP_SDIDATA;
436 /* Set up card detect input on gpio port a and set up the irq
437 * trigger
439 samcop_set_gpio_int(dev->parent, 2, SAMCOP_GPIO_IRQT_MASK(0),
440 SAMCOP_GPIO_IRQT_BOTHEDGE << SAMCOP_SD_WAKEUP_IRQT_SHIFT);
441 samcop_set_gpio_int(dev->parent, 2, SAMCOP_GPIO_IRQF_MASK(0), 0);
442 samcop_set_gpio_int_enable(dev->parent, 0, SAMCOP_GPIO_ENINT_MASK(8),
443 1 << SAMCOP_SD_WAKEUP_ENINT_SHIFT);
444 samcop_set_gpio_a_con(dev->parent, 1, SAMCOP_GPIO_GPx_CON_MASK(0),
445 SAMCOP_GPIO_GPx_CON_MODE(0, EXTIN));
447 /* provide the right card detect irq to the mmc subsystem by
448 * applying the samcop irq_base offset
450 plat->irq_cd = plat->irq_cd + samcop_irq_base(dev->parent);
452 /* setup DMA (including dma_bounce) */
453 dev->dma_mask = &samcop_sdi_dmamask; /* spread the address range wide
454 * so we can DMA bounce wherever
455 * we want.
457 dev->coherent_dma_mask = samcop_sdi_dmamask;
458 dmabounce_register_dev(dev, 512, 4096);
459 pxa_set_dma_needs_bounce(samcop_dma_needs_bounce);
462 static void
463 samcop_sdi_exit(struct device *dev)
465 dmabounce_unregister_dev(dev);
468 static u32
469 samcop_sdi_read_register(struct device *dev, u32 reg)
471 struct samcop_data *samcop = dev->parent->driver_data;
473 return samcop_read_register(samcop, _SAMCOP_SDI_Base + reg);
476 static void
477 samcop_sdi_write_register(struct device *dev, u32 reg, u32 val)
479 struct samcop_data *samcop = dev->parent->driver_data;
481 samcop_write_register(samcop, _SAMCOP_SDI_Base + reg, val);
484 static void
485 samcop_sdi_card_power(struct device *dev, int on, int clock_req)
487 struct samcop_data *samcop = dev->parent->driver_data;
488 u32 sdi_psc = 1, sdi_con;
489 int clock_rate;
491 /* Set power */
492 sdi_con = samcop_sdi_read_register(dev, SAMCOP_SDICON);
493 #ifdef CONFIG_ARCH_H5400
494 /* apply proper power setting to the sd slot */
495 if (machine_is_h5400())
496 SET_H5400_GPIO(POWER_SD_N, on != 0);
497 #endif
499 if (on) {
500 /* enable pullups */
501 samcop_set_spcr(dev->parent, SAMCOP_GPIO_SPCR_SDPUCR, 0);
502 samcop_set_gpio_a_pullup(dev->parent, SAMCOP_GPIO_GPA_SD_DETECT_N, 0);
504 /* enable the SD clock prescaler and clear the fifo */
505 sdi_con |= SAMCOP_SDICON_FIFORESET | SAMCOP_SDICON_CLOCKTYPE;
506 } else {
507 /* remove power from the sd slot */
508 #ifdef CONFIG_ARCH_H5400
509 if (machine_is_h5400())
510 SET_H5400_GPIO(POWER_SD_N, 0);
511 #endif
513 /* disable pullups */
514 samcop_set_spcr(dev->parent, SAMCOP_GPIO_SPCR_SDPUCR,
515 SAMCOP_GPIO_SPCR_SDPUCR);
516 samcop_set_gpio_a_pullup(dev->parent,
517 SAMCOP_GPIO_GPA_SD_DETECT_N,
518 SAMCOP_GPIO_GPA_SD_DETECT_N);
520 sdi_con &= ~SAMCOP_SDICON_CLOCKTYPE;
523 clock_rate = samcop_gclk(samcop);
525 if (clock_req == 0) {
526 /* Don't set the prescaler or enable the card clock if the mmc
527 * subsystem is sending a 0 clock rate.
529 sdi_con &= ~SAMCOP_SDICON_CLOCKTYPE;
530 } else if (clock_req < (clock_rate / 256)) {
531 printk(KERN_WARNING
532 "%s: MMC subsystem requesting bogus clock rate %d. "
533 "Hardcoding prescaler to 255\n",
534 __FUNCTION__, clock_req);
535 sdi_psc = 255;
536 } else {
537 sdi_psc = clock_rate / clock_req - 1;
538 if (sdi_psc > 255) {
539 printk(KERN_WARNING
540 "%s: calculated prescaler %d is too high. "
541 "Hardcoding prescaler to 255\n",
542 __FUNCTION__, sdi_psc);
543 sdi_psc = 255;
544 } else if (sdi_psc < 1) {
545 printk(KERN_WARNING
546 "%s: calculated prescaler %d is too low. "
547 "Hardcoding prescaler to 1\n",
548 __FUNCTION__, sdi_psc);
549 sdi_psc = 1;
553 samcop_sdi_write_register(dev, SAMCOP_SDICON, sdi_con);
555 if (clock_req != 0 && on) {
556 if (clock_rate / (sdi_psc + 1) > clock_req && sdi_psc < 255)
557 sdi_psc++;
558 samcop_sdi_write_register(dev, SAMCOP_SDIPRE, sdi_psc);
559 /* wait for the prescribed time that the card requires to init */
560 if ((clock_rate / sdi_psc) > 1000000UL)
561 ndelay(sdi_psc * 1000000000UL / clock_rate * SAMCOP_CARD_INIT_CYCLES);
562 else
563 udelay(sdi_psc * 1000000UL / clock_rate * SAMCOP_CARD_INIT_CYCLES);
567 static struct samcop_sdi_data samcop_sdi_data = {
568 .init = samcop_sdi_init,
569 .exit = samcop_sdi_exit,
570 .read_reg = samcop_sdi_read_register,
571 .write_reg = samcop_sdi_write_register,
572 .card_power = samcop_sdi_card_power,
573 /* card detect IRQ. Macro is for the samcop number,
574 * use samcop->irq_base + irq_cd to get the irq system number
576 .irq_cd = _IRQ_SAMCOP_SD_WAKEUP,
577 .f_min = 0, /* this will be set by sdi_init */
578 .f_max = 0, /* this will be set by sdi_init */
579 /* SAMCOP has 32KB of SRAM, 32KB / 512B (per sector) = 64 sectors max.*/
580 .max_sectors = 64,
581 .timeout = SAMCOP_SDI_TIMER_MAX,
583 /* DMA specific settings */
584 .dma_chan = 0, /* hardcoded for now */
585 .dma_devaddr = (void *)_SAMCOP_SDI_Base + SAMCOP_SDIDATA,
586 .hwsrcsel = SAMCOP_DCON_CH0_SD,
587 /* SAMCOP supports 32bit transfers, 32/8 = 4 bytes per transfer unit */
588 .xfer_unit = 4,
591 /*************************************************************
592 * SAMCOP DMA interface hooks and initialization
593 *************************************************************/
595 static struct samcop_dma_plat_data samcop_dma_plat_data = {
596 .n_channels = 2,
599 /*************************************************************/
602 samcop_clock_enable (struct clk* clk, int enable)
604 unsigned long flags, val;
605 struct samcop_data *samcop = (struct samcop_data *)clk->priv;
607 local_irq_save (flags);
608 val = samcop_read_register (samcop, SAMCOP_CPM_ClockControl);
610 /* UCLK is different from the rest (0 = on, 1 = off), so we
611 * special-case it here. */
612 if (strcmp(clk->name, "uclk") == 0)
613 enable = enable ? 0 : 1;
615 if (enable)
616 val |= clk->ctrlbit;
617 else
618 val &= ~clk->ctrlbit;
619 samcop_write_register (samcop, SAMCOP_CPM_ClockControl, val);
620 local_irq_restore (flags);
622 return 0;
624 EXPORT_SYMBOL(samcop_clock_enable);
626 static int
627 samcop_gclk (void *ptr)
629 struct samcop_data *samcop = ptr;
630 int half_clk;
631 unsigned int memory_clock = get_memclk_frequency_10khz() * 10000;
633 half_clk = (samcop_read_register (samcop, SAMCOP_CPM_ClockSleep) & SAMCOP_CPM_CLKSLEEP_HALF_CLK);
635 return half_clk ? memory_clock : memory_clock / 2;
638 void
639 samcop_set_gpio_a (struct device *dev, u32 mask, u32 bits)
641 struct samcop_data *samcop = dev->driver_data;
642 unsigned long flags, val;
644 spin_lock_irqsave (&samcop->gpio_lock, flags);
645 val = samcop_read_register (samcop, SAMCOP_GPIO_GPA_DAT) & ~mask;
646 val |= bits;
647 samcop_write_register (samcop, SAMCOP_GPIO_GPA_DAT, val);
648 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
650 EXPORT_SYMBOL(samcop_set_gpio_a);
652 static void
653 samcop_set_gpio_a_pullup (struct device *dev, u32 mask, u32 bits)
655 struct samcop_data *samcop = dev->driver_data;
656 unsigned long flags, val;
658 spin_lock_irqsave (&samcop->gpio_lock, flags);
659 val = samcop_read_register (samcop, SAMCOP_GPIO_GPA_PUP) & ~mask;
660 val |= bits;
661 samcop_write_register (samcop, SAMCOP_GPIO_GPA_PUP, val);
662 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
665 static void
666 samcop_set_gpio_a_con (struct device *dev, unsigned int idx, u32 mask, u32 bits)
668 struct samcop_data *samcop = dev->driver_data;
669 unsigned long flags;
670 u32 val;
672 if (idx > 1) {
673 printk(KERN_WARNING "%s idx %u is invalid, must be {0-1}\n",
674 __FUNCTION__, idx);
675 return;
678 spin_lock_irqsave (&samcop->gpio_lock, flags);
679 val = samcop_read_register (samcop, SAMCOP_GPIO_GPA_CON(idx)) & ~mask;
680 val |= bits;
681 samcop_write_register (samcop, SAMCOP_GPIO_GPA_CON(idx), val);
682 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
686 samcop_get_gpio_a (struct device *dev)
688 struct samcop_data *samcop = dev->driver_data;
690 return samcop_read_register (samcop, SAMCOP_GPIO_GPA_DAT);
692 EXPORT_SYMBOL(samcop_get_gpio_a);
694 void
695 samcop_set_gpio_b (struct device *dev, u32 mask, u32 bits)
697 struct samcop_data *samcop = dev->driver_data;
698 unsigned long flags, val;
700 spin_lock_irqsave (&samcop->gpio_lock, flags);
701 val = samcop_read_register (samcop, SAMCOP_GPIO_GPB_DAT) & ~mask;
702 val |= bits;
703 samcop_write_register (samcop, SAMCOP_GPIO_GPB_DAT, val);
704 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
706 EXPORT_SYMBOL(samcop_set_gpio_b);
709 samcop_get_gpio_b (struct device *dev)
711 struct samcop_data *samcop = dev->driver_data;
713 return samcop_read_register (samcop, SAMCOP_GPIO_GPB_DAT);
715 EXPORT_SYMBOL(samcop_get_gpio_b);
717 void
718 samcop_set_gpio_int (struct device *dev, unsigned int idx, u32 mask, u32 bits)
720 struct samcop_data *samcop = dev->driver_data;
721 unsigned long flags, val;
723 if (idx > 2) {
724 printk(KERN_WARNING "%s idx %u is invalid, must be {0-2}\n",
725 __FUNCTION__, idx);
726 return;
729 spin_lock_irqsave (&samcop->gpio_lock, flags);
730 val = samcop_read_register (samcop, SAMCOP_GPIO_INT(idx)) & ~mask;
731 val |= bits;
732 samcop_write_register (samcop, SAMCOP_GPIO_INT(idx), val);
733 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
736 void
737 samcop_set_gpio_filter_config (struct device *dev, unsigned int idx, u32 mask,
738 u32 bits)
740 struct samcop_data *samcop = dev->driver_data;
741 unsigned long flags, val;
743 if (idx > 6) {
744 printk(KERN_WARNING "%s idx %u is invalid, must be {0-6}\n",
745 __FUNCTION__, idx);
746 return;
749 spin_lock_irqsave (&samcop->gpio_lock, flags);
750 val = samcop_read_register (samcop, SAMCOP_GPIO_FLTCONFIG(idx)) & ~mask;
751 val |= bits;
752 samcop_write_register (samcop, SAMCOP_GPIO_FLTCONFIG(idx), val);
753 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
756 void
757 samcop_set_gpio_int_enable (struct device *dev, unsigned int idx, u32 mask,
758 u32 bits)
760 struct samcop_data *samcop = dev->driver_data;
761 unsigned long flags, val;
763 if (idx > 1) {
764 printk(KERN_WARNING "%s idx %u is invalid, must be {0,1}\n",
765 __FUNCTION__, idx);
766 return;
769 spin_lock_irqsave (&samcop->gpio_lock, flags);
770 val = samcop_read_register (samcop, SAMCOP_GPIO_ENINT(idx)) & ~mask;
771 val |= bits;
772 samcop_write_register (samcop, SAMCOP_GPIO_ENINT(idx), val);
773 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
776 void
777 samcop_reset_fcd (struct device *dev)
779 struct samcop_data *samcop = dev->driver_data;
780 unsigned long flags;
782 spin_lock_irqsave (&samcop->gpio_lock, flags);
783 samcop_write_register (samcop, SAMCOP_GPIO_GPD_CON, SAMCOP_GPIO_GPD_CON_RESET);
784 samcop_write_register(samcop, SAMCOP_GPIO_GPE_CON, SAMCOP_GPIO_GPE_CON_RESET);
785 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
787 EXPORT_SYMBOL(samcop_reset_fcd);
790 samcop_irq_base (struct device *dev)
792 struct samcop_data *samcop = dev->driver_data;
794 return samcop->irq_base;
796 EXPORT_SYMBOL(samcop_irq_base);
798 void
799 samcop_set_spcr (struct device *dev, u32 mask, u32 bits)
801 struct samcop_data *samcop = dev->driver_data;
802 unsigned long flags;
803 u32 val;
805 spin_lock_irqsave (&samcop->gpio_lock, flags);
806 val = samcop_read_register (samcop, SAMCOP_GPIO_SPCR);
807 val &= ~mask;
808 val |= bits;
809 samcop_write_register (samcop, SAMCOP_GPIO_SPCR, val);
810 spin_unlock_irqrestore (&samcop->gpio_lock, flags);
812 EXPORT_SYMBOL(samcop_set_spcr);
815 /*************************************************************
816 SAMCOP clocks
817 *************************************************************/
819 /* base clocks */
821 static struct clk clk_g = {
822 .name = "gclk",
823 .id = -1,
824 .rate = 0,
825 .parent = NULL,
826 .ctrlbit = 0,
829 /* clock definitions */
831 static struct clk samcop_clocks[] = {
832 { .name = "uclk",
833 .id = -1,
834 .parent = &clk_g,
835 .enable = samcop_clock_enable,
836 /* note that the sense of this uclk bit is reversed */
837 .ctrlbit = SAMCOP_CPM_CLKCON_UCLK_EN
839 { .name = "usb",
840 .id = -1,
841 .parent = &clk_g,
842 .enable = samcop_clock_enable,
843 .ctrlbit = SAMCOP_CPM_CLKCON_USBHOST_CLKEN
845 { .name = "dma",
846 .id = -1,
847 .parent = &clk_g,
848 .enable = samcop_clock_enable,
849 .ctrlbit = SAMCOP_CPM_CLKCON_DMAC_CLKEN
851 { .name = "gpio",
852 .id = -1,
853 .parent = &clk_g,
854 .enable = samcop_clock_enable,
855 .ctrlbit = SAMCOP_CPM_CLKCON_GPIO_CLKEN
857 { .name = "fsi",
858 .id = -1,
859 .parent = &clk_g,
860 .enable = samcop_clock_enable,
861 .ctrlbit = SAMCOP_CPM_CLKCON_FCD_CLKEN
863 { .name = "sdi",
864 .id = -1,
865 .parent = &clk_g,
866 .enable = samcop_clock_enable,
867 .ctrlbit = SAMCOP_CPM_CLKCON_SD_CLKEN
869 { .name = "adc",
870 .id = -1,
871 .parent = &clk_g,
872 .enable = samcop_clock_enable,
873 .ctrlbit = SAMCOP_CPM_CLKCON_ADC_CLKEN
875 { .name = "uart2",
876 .id = -1,
877 .parent = &clk_g,
878 .enable = samcop_clock_enable,
879 .ctrlbit = SAMCOP_CPM_CLKCON_UART2_CLKEN
881 { .name = "uart1",
882 .id = -1,
883 .parent = &clk_g,
884 .enable = samcop_clock_enable,
885 .ctrlbit = SAMCOP_CPM_CLKCON_UART1_CLKEN
887 { .name = "led",
888 .id = -1,
889 .parent = &clk_g,
890 .enable = samcop_clock_enable,
891 .ctrlbit = SAMCOP_CPM_CLKCON_LED_CLKEN
893 { .name = "misc",
894 .id = -1,
895 .parent = &clk_g,
896 .enable = samcop_clock_enable,
897 .ctrlbit = SAMCOP_CPM_CLKCON_MISC_CLKEN
899 { .name = "w1",
900 .id = -1,
901 .parent = &clk_g,
902 .enable = samcop_clock_enable,
903 .ctrlbit = SAMCOP_CPM_CLKCON_1WIRE_CLKEN
907 /*************************************************************/
909 struct samcop_block
911 platform_device_id id;
912 char *name;
913 unsigned long start, end;
914 unsigned long irq;
915 void *platform_data;
918 static struct samcop_block samcop_blocks[] = {
920 .id = { -1 },
921 .name = "samcop adc",
922 .start = _SAMCOP_ADC_Base,
923 .end = _SAMCOP_ADC_Base + 0x1f,
924 .irq = _IRQ_SAMCOP_ADCTS,
927 .id = { -1 },
928 .name = "samcop owm",
929 .start = _SAMCOP_OWM_Base,
930 .end = _SAMCOP_OWM_Base + 0x1f, /* 0x47 */
931 .irq = _IRQ_SAMCOP_ONEWIRE,
934 .id = { -1 },
935 .name = "samcop fsi",
936 .start = _SAMCOP_FSI_Base,
937 .end = _SAMCOP_FSI_Base + 0x1f,
938 .irq = _IRQ_SAMCOP_FCD,
941 .id = { -1 },
942 .name = "samcop sleeve",
943 .start = _SAMCOP_PCMCIA_Base,
944 .end = _SAMCOP_PCMCIA_Base + 0x1f,
945 .irq = SAMCOP_EPS_IRQ_START,
948 .id = { -1 },
949 .name = "samcop dma",
950 .start = _SAMCOP_DMAC_Base,
951 .end = _SAMCOP_DMAC_Base + 0x3f,
952 .irq = _IRQ_SAMCOP_DMA0,
953 .platform_data = &samcop_dma_plat_data,
956 .id = { -1 },
957 .name = "samcop sdi",
958 .start = _SAMCOP_SDI_Base,
959 .end = _SAMCOP_SDI_Base + 0x43,
960 .irq = _IRQ_SAMCOP_SD,
961 .platform_data = &samcop_sdi_data,
964 .id = { -1 },
965 .name = "samcop usb host",
966 .start = _SAMCOP_USBHOST_Base,
967 .end = _SAMCOP_USBHOST_Base + 0xffff,
968 .irq = _IRQ_SAMCOP_USBH,
972 static void
973 samcop_release (struct device *dev)
975 struct platform_device *sdev = to_platform_device (dev);
976 kfree (sdev->resource);
977 kfree (sdev);
980 static int
981 samcop_probe (struct device *dev)
983 int i, rc;
984 struct platform_device *pdev = to_platform_device (dev);
985 struct samcop_platform_data *platform_data = dev->platform_data;
986 struct samcop_data *samcop;
988 samcop = kmalloc (sizeof (struct samcop_data), GFP_KERNEL);
989 if (!samcop)
990 goto enomem3;
991 memset (samcop, 0, sizeof (*samcop));
992 dev->driver_data = samcop;
994 samcop->irq_nr = platform_get_irq(pdev, 0);
995 samcop->irq_base = alloc_irq_space (SAMCOP_NR_IRQS);
996 if (samcop->irq_base == -1) {
997 printk("samcop: unable to allocate %d irqs\n", SAMCOP_NR_IRQS);
998 goto enomem2;
1001 samcop->mapping = ioremap ((unsigned long)pdev->resource[0].start, SAMCOP_MAP_SIZE);
1002 if (!samcop->mapping) {
1003 printk ("samcop: couldn't ioremap\n");
1004 goto enomem1;
1007 if (dma_declare_coherent_memory (dev,
1008 pdev->resource[0].start + _SAMCOP_SRAM_Base,
1009 _SAMCOP_SRAM_Base, SAMCOP_SRAM_SIZE,
1010 DMA_MEMORY_MAP | DMA_MEMORY_INCLUDES_CHILDREN |
1011 DMA_MEMORY_EXCLUSIVE) != DMA_MEMORY_MAP) {
1012 printk ("samcop: couldn't declare coherent dma memory\n");
1013 goto enomem0;
1016 printk ("%s: using irq %d-%d on irq %d\n", pdev->name, samcop->irq_base,
1017 samcop->irq_base + SAMCOP_NR_IRQS - 1, samcop->irq_nr);
1019 samcop_write_register (samcop, SAMCOP_CPM_ClockControl, SAMCOP_CPM_CLKCON_GPIO_CLKEN);
1020 samcop_write_register (samcop, SAMCOP_CPM_ClockSleep, platform_data->clocksleep);
1021 samcop_write_register (samcop, SAMCOP_CPM_PllControl, platform_data->pllcontrol);
1023 samcop_irq_init (samcop);
1025 #ifdef CONFIG_ARCH_H5400
1026 h5400_set_samcop_gpio_b = samcop_set_gpio_b;
1027 #endif
1029 /* Register SAMCOP's clocks. */
1030 clk_g.rate = samcop_gclk(samcop);
1032 if (clk_register(&clk_g) < 0)
1033 printk(KERN_ERR "failed to register SAMCOP gclk\n");
1035 for (i = 0; i < ARRAY_SIZE(samcop_clocks); i++) {
1036 samcop_clocks[i].priv = (unsigned long)samcop;
1037 rc = clk_register(&samcop_clocks[i]);
1038 if (rc < 0)
1039 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1040 samcop_clocks[i].name, rc);
1043 /* Register SAMCOP's platform devices. */
1044 samcop->ndevices = ARRAY_SIZE (samcop_blocks);
1045 samcop->devices = kmalloc (samcop->ndevices * sizeof (struct platform_device *), GFP_KERNEL);
1046 if (unlikely (!samcop->devices))
1047 goto enomem;
1048 memset (samcop->devices, 0, samcop->ndevices * sizeof (struct platform_device *));
1050 for (i = 0; i < samcop->ndevices; i++) {
1051 struct platform_device *sdev;
1052 struct samcop_block *blk = &samcop_blocks[i];
1053 struct resource *res;
1055 sdev = kmalloc (sizeof (*sdev), GFP_KERNEL);
1056 if (unlikely (!sdev))
1057 goto enomem;
1058 memset (sdev, 0, sizeof (*sdev));
1059 sdev->id = samcop_blocks[i].id.id;
1060 sdev->dev.parent = dev;
1061 sdev->dev.platform_data = samcop_blocks[i].platform_data;
1062 sdev->dev.release = samcop_release;
1063 sdev->num_resources = (blk->irq == -1) ? 1 : 2;
1064 sdev->name = blk->name;
1065 res = kmalloc (sdev->num_resources * sizeof (struct resource), GFP_KERNEL);
1066 if (unlikely (!res))
1067 goto enomem;
1068 sdev->resource = res;
1069 memset (res, 0, sdev->num_resources * sizeof (struct resource));
1070 res[0].start = blk->start + pdev->resource[0].start;
1071 res[0].end = blk->end + pdev->resource[0].start;
1072 res[0].flags = IORESOURCE_MEM;
1073 res[0].parent = &pdev->resource[0];
1074 if (blk->irq != -1) {
1075 res[1].start = blk->irq + samcop->irq_base;
1076 res[1].end = res[1].start;
1077 res[1].flags = IORESOURCE_IRQ;
1079 sdev->dev.dma_mem = dev->dma_mem;
1080 rc = platform_device_register (sdev);
1081 if (unlikely (rc != 0)) {
1082 printk ("samcop: could not register %s\n", blk->name);
1083 kfree (sdev->resource);
1084 kfree (sdev);
1085 goto error;
1087 samcop->devices[i] = sdev;
1090 return 0;
1092 enomem:
1093 rc = -ENOMEM;
1094 error:
1095 samcop_remove (dev);
1096 return rc;
1098 enomem0:
1099 iounmap (samcop->mapping);
1100 enomem1:
1101 free_irq_space (samcop->irq_base, SAMCOP_NR_IRQS);
1102 enomem2:
1103 kfree (samcop);
1104 enomem3:
1105 return -ENOMEM;
1108 static int
1109 samcop_remove (struct device *dev)
1111 int i;
1112 struct samcop_data *samcop;
1114 samcop = dev->driver_data;
1116 samcop_write_register (samcop, SAMCOP_PCMCIA_IC, 0); /* nothing enabled */
1117 samcop_write_register (samcop, SAMCOP_GPIO_ENINT1, 0);
1118 samcop_write_register (samcop, SAMCOP_GPIO_ENINT2, 0);
1119 samcop_write_register (samcop, SAMCOP_IC_INTMSK, 0xffffffff);
1121 for (i = 0; i < SAMCOP_NR_IRQS; i++) {
1122 int irq = i + samcop->irq_base;
1123 set_irq_flags(irq, 0);
1124 set_irq_handler (irq, NULL);
1125 set_irq_chip (irq, NULL);
1126 set_irq_chipdata (irq, NULL);
1129 set_irq_chained_handler (samcop->irq_nr, NULL);
1131 if (samcop->devices) {
1132 for (i = 0; i < samcop->ndevices; i++) {
1133 if (samcop->devices[i])
1134 platform_device_unregister (samcop->devices[i]);
1136 kfree (samcop->devices);
1139 for (i = 0; i < ARRAY_SIZE(samcop_clocks); i++)
1140 clk_unregister(&samcop_clocks[i]);
1141 clk_unregister(&clk_g);
1143 samcop_write_register (samcop, SAMCOP_CPM_ClockControl, 0);
1145 dma_release_declared_memory (dev);
1146 iounmap (samcop->mapping);
1147 free_irq_space (samcop->irq_base, SAMCOP_NR_IRQS);
1149 kfree (samcop);
1151 return 0;
1154 static void
1155 samcop_shutdown (struct device *dev)
1159 static int
1160 samcop_suspend (struct device *dev, pm_message_t state)
1162 struct samcop_data *samcop;
1164 samcop = dev->driver_data;
1166 samcop->irqmask = samcop_read_register (samcop, SAMCOP_IC_INTMSK);
1167 if (samcop->irqmask != 0xffffffff) {
1168 samcop_write_register (samcop, SAMCOP_IC_INTMSK, 0xffffffff);
1169 printk (KERN_WARNING "irqs %08lx still enabled\n", ~samcop->irqmask);
1172 return 0;
1175 static int
1176 samcop_resume (struct device *dev)
1178 struct samcop_data *samcop;
1180 samcop = dev->driver_data;
1182 if (samcop->irqmask != 0xffffffff)
1183 samcop_write_register (samcop, SAMCOP_IC_INTMSK, samcop->irqmask);
1185 return 0;
1188 static struct device_driver samcop_device_driver = {
1189 .name = "samcop",
1190 .bus = &platform_bus_type,
1192 .probe = samcop_probe,
1193 .remove = samcop_remove,
1194 .suspend = samcop_suspend,
1195 .resume = samcop_resume,
1196 .shutdown = samcop_shutdown,
1199 static int __init
1200 samcop_base_init (void)
1202 int retval = 0;
1203 retval = driver_register (&samcop_device_driver);
1204 return retval;
1207 static void __exit
1208 samcop_base_exit (void)
1210 driver_unregister (&samcop_device_driver);
1213 module_init (samcop_base_init)
1214 module_exit (samcop_base_exit)
1216 MODULE_AUTHOR("Jamey Hicks <jamey@handhelds.org>");
1217 MODULE_DESCRIPTION("Base platform_device driver for the SAMCOP chip");
1218 MODULE_LICENSE("Dual BSD/GPL");
1219 MODULE_SUPPORTED_DEVICE("samcop");