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>
16 #include <asm/hardware/scoop.h>
18 #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
22 spinlock_t scoop_lock
;
26 void reset_scoop(struct device
*dev
)
28 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
30 SCOOP_REG(sdev
->base
,SCOOP_MCR
) = 0x0100; // 00
31 SCOOP_REG(sdev
->base
,SCOOP_CDR
) = 0x0000; // 04
32 SCOOP_REG(sdev
->base
,SCOOP_CPR
) = 0x0000; // 0C
33 SCOOP_REG(sdev
->base
,SCOOP_CCR
) = 0x0000; // 10
34 SCOOP_REG(sdev
->base
,SCOOP_IMR
) = 0x0000; // 18
35 SCOOP_REG(sdev
->base
,SCOOP_IRM
) = 0x00FF; // 14
36 SCOOP_REG(sdev
->base
,SCOOP_ISR
) = 0x0000; // 1C
37 SCOOP_REG(sdev
->base
,SCOOP_IRM
) = 0x0000;
40 unsigned short set_scoop_gpio(struct device
*dev
, unsigned short bit
)
42 unsigned short gpio_bit
;
44 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
46 spin_lock_irqsave(&sdev
->scoop_lock
, flag
);
47 gpio_bit
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
) | bit
;
48 SCOOP_REG(sdev
->base
, SCOOP_GPWR
) = gpio_bit
;
49 spin_unlock_irqrestore(&sdev
->scoop_lock
, flag
);
54 unsigned short reset_scoop_gpio(struct device
*dev
, unsigned short bit
)
56 unsigned short gpio_bit
;
58 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
60 spin_lock_irqsave(&sdev
->scoop_lock
, flag
);
61 gpio_bit
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
) & ~bit
;
62 SCOOP_REG(sdev
->base
,SCOOP_GPWR
) = gpio_bit
;
63 spin_unlock_irqrestore(&sdev
->scoop_lock
, flag
);
68 EXPORT_SYMBOL(set_scoop_gpio
);
69 EXPORT_SYMBOL(reset_scoop_gpio
);
71 unsigned short read_scoop_reg(struct device
*dev
, unsigned short reg
)
73 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
74 return SCOOP_REG(sdev
->base
,reg
);
77 void write_scoop_reg(struct device
*dev
, unsigned short reg
, unsigned short data
)
79 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
80 SCOOP_REG(sdev
->base
,reg
)=data
;
83 EXPORT_SYMBOL(reset_scoop
);
84 EXPORT_SYMBOL(read_scoop_reg
);
85 EXPORT_SYMBOL(write_scoop_reg
);
88 static int scoop_suspend(struct device
*dev
, uint32_t state
, uint32_t level
)
90 if (level
== SUSPEND_POWER_DOWN
) {
91 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
93 sdev
->scoop_gpwr
= SCOOP_REG(sdev
->base
,SCOOP_GPWR
);
94 SCOOP_REG(sdev
->base
,SCOOP_GPWR
) = 0;
99 static int scoop_resume(struct device
*dev
, uint32_t level
)
101 if (level
== RESUME_POWER_ON
) {
102 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
104 SCOOP_REG(sdev
->base
,SCOOP_GPWR
) = sdev
->scoop_gpwr
;
109 #define scoop_suspend NULL
110 #define scoop_resume NULL
113 int __init
scoop_probe(struct device
*dev
)
115 struct scoop_dev
*devptr
;
116 struct scoop_config
*inf
;
117 struct platform_device
*pdev
= to_platform_device(dev
);
118 struct resource
*mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
123 devptr
= kmalloc(sizeof(struct scoop_dev
), GFP_KERNEL
);
128 memset(devptr
, 0, sizeof(struct scoop_dev
));
129 spin_lock_init(&devptr
->scoop_lock
);
131 inf
= dev
->platform_data
;
132 devptr
->base
= ioremap(mem
->start
, mem
->end
- mem
->start
+ 1);
139 dev_set_drvdata(dev
, devptr
);
141 printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem
->start
,(unsigned int)devptr
->base
);
143 SCOOP_REG(devptr
->base
, SCOOP_MCR
) = 0x0140;
145 SCOOP_REG(devptr
->base
, SCOOP_GPCR
) = inf
->io_dir
& 0xffff;
146 SCOOP_REG(devptr
->base
, SCOOP_GPWR
) = inf
->io_out
& 0xffff;
151 static int scoop_remove(struct device
*dev
)
153 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
157 dev_set_drvdata(dev
, NULL
);
162 static struct device_driver scoop_driver
= {
163 .name
= "sharp-scoop",
164 .bus
= &platform_bus_type
,
165 .probe
= scoop_probe
,
166 .remove
= scoop_remove
,
167 .suspend
= scoop_suspend
,
168 .resume
= scoop_resume
,
171 int __init
scoop_init(void)
173 return driver_register(&scoop_driver
);
176 subsys_initcall(scoop_init
);