2 * Support code for the SCOOP interface found on various Sharp PDAs
4 * Copyright (c) 2004 Richard Purdie
6 * Based on code written by Sharp/Lineo for 2.4 kernels
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 #include <linux/device.h>
15 #include <linux/string.h>
16 #include <linux/slab.h>
19 #include <asm/hardware/scoop.h>
21 #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
23 /* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
24 There is no easy way to link multiple scoop devices into one
25 single entity for the pxa2xx_pcmcia device */
27 struct scoop_pcmcia_dev
*scoop_devs
;
31 spinlock_t scoop_lock
;
32 unsigned short suspend_clr
;
33 unsigned short suspend_set
;
37 void reset_scoop(struct device
*dev
)
39 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
41 SCOOP_REG(sdev
->base
,SCOOP_MCR
) = 0x0100; // 00
42 SCOOP_REG(sdev
->base
,SCOOP_CDR
) = 0x0000; // 04
43 SCOOP_REG(sdev
->base
,SCOOP_CPR
) = 0x0000; // 0C
44 SCOOP_REG(sdev
->base
,SCOOP_CCR
) = 0x0000; // 10
45 SCOOP_REG(sdev
->base
,SCOOP_IMR
) = 0x0000; // 18
46 SCOOP_REG(sdev
->base
,SCOOP_IRM
) = 0x00FF; // 14
47 SCOOP_REG(sdev
->base
,SCOOP_ISR
) = 0x0000; // 1C
48 SCOOP_REG(sdev
->base
,SCOOP_IRM
) = 0x0000;
51 unsigned short set_scoop_gpio(struct device
*dev
, unsigned short bit
)
53 unsigned short gpio_bit
;
55 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
57 spin_lock_irqsave(&sdev
->scoop_lock
, flag
);
58 gpio_bit
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
) | bit
;
59 SCOOP_REG(sdev
->base
, SCOOP_GPWR
) = gpio_bit
;
60 spin_unlock_irqrestore(&sdev
->scoop_lock
, flag
);
65 unsigned short reset_scoop_gpio(struct device
*dev
, unsigned short bit
)
67 unsigned short gpio_bit
;
69 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
71 spin_lock_irqsave(&sdev
->scoop_lock
, flag
);
72 gpio_bit
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
) & ~bit
;
73 SCOOP_REG(sdev
->base
,SCOOP_GPWR
) = gpio_bit
;
74 spin_unlock_irqrestore(&sdev
->scoop_lock
, flag
);
79 EXPORT_SYMBOL(set_scoop_gpio
);
80 EXPORT_SYMBOL(reset_scoop_gpio
);
82 unsigned short read_scoop_reg(struct device
*dev
, unsigned short reg
)
84 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
85 return SCOOP_REG(sdev
->base
,reg
);
88 void write_scoop_reg(struct device
*dev
, unsigned short reg
, unsigned short data
)
90 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
91 SCOOP_REG(sdev
->base
,reg
)=data
;
94 EXPORT_SYMBOL(reset_scoop
);
95 EXPORT_SYMBOL(read_scoop_reg
);
96 EXPORT_SYMBOL(write_scoop_reg
);
98 static void check_scoop_reg(struct scoop_dev
*sdev
)
102 mcr
= SCOOP_REG(sdev
->base
, SCOOP_MCR
);
103 if ((mcr
& 0x100) == 0)
104 SCOOP_REG(sdev
->base
, SCOOP_MCR
) = 0x0101;
108 static int scoop_suspend(struct device
*dev
, pm_message_t state
)
110 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
112 check_scoop_reg(sdev
);
113 sdev
->scoop_gpwr
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
);
114 SCOOP_REG(sdev
->base
, SCOOP_GPWR
) = (sdev
->scoop_gpwr
& ~sdev
->suspend_clr
) | sdev
->suspend_set
;
119 static int scoop_resume(struct device
*dev
)
121 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
123 check_scoop_reg(sdev
);
124 SCOOP_REG(sdev
->base
,SCOOP_GPWR
) = sdev
->scoop_gpwr
;
129 #define scoop_suspend NULL
130 #define scoop_resume NULL
133 int __init
scoop_probe(struct device
*dev
)
135 struct scoop_dev
*devptr
;
136 struct scoop_config
*inf
;
137 struct platform_device
*pdev
= to_platform_device(dev
);
138 struct resource
*mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
143 devptr
= kmalloc(sizeof(struct scoop_dev
), GFP_KERNEL
);
148 memset(devptr
, 0, sizeof(struct scoop_dev
));
149 spin_lock_init(&devptr
->scoop_lock
);
151 inf
= dev
->platform_data
;
152 devptr
->base
= ioremap(mem
->start
, mem
->end
- mem
->start
+ 1);
159 dev_set_drvdata(dev
, devptr
);
161 printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem
->start
,(unsigned int)devptr
->base
);
163 SCOOP_REG(devptr
->base
, SCOOP_MCR
) = 0x0140;
165 SCOOP_REG(devptr
->base
, SCOOP_GPCR
) = inf
->io_dir
& 0xffff;
166 SCOOP_REG(devptr
->base
, SCOOP_GPWR
) = inf
->io_out
& 0xffff;
168 devptr
->suspend_clr
= inf
->suspend_clr
;
169 devptr
->suspend_set
= inf
->suspend_set
;
174 static int scoop_remove(struct device
*dev
)
176 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
180 dev_set_drvdata(dev
, NULL
);
185 static struct device_driver scoop_driver
= {
186 .name
= "sharp-scoop",
187 .bus
= &platform_bus_type
,
188 .probe
= scoop_probe
,
189 .remove
= scoop_remove
,
190 .suspend
= scoop_suspend
,
191 .resume
= scoop_resume
,
194 int __init
scoop_init(void)
196 return driver_register(&scoop_driver
);
199 subsys_initcall(scoop_init
);