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)))
20 /* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
21 There is no easy way to link multiple scoop devices into one
22 single entity for the pxa2xx_pcmcia device */
24 struct scoop_pcmcia_dev
*scoop_devs
;
28 spinlock_t scoop_lock
;
29 unsigned short suspend_clr
;
30 unsigned short suspend_set
;
34 void reset_scoop(struct device
*dev
)
36 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
38 SCOOP_REG(sdev
->base
,SCOOP_MCR
) = 0x0100; // 00
39 SCOOP_REG(sdev
->base
,SCOOP_CDR
) = 0x0000; // 04
40 SCOOP_REG(sdev
->base
,SCOOP_CPR
) = 0x0000; // 0C
41 SCOOP_REG(sdev
->base
,SCOOP_CCR
) = 0x0000; // 10
42 SCOOP_REG(sdev
->base
,SCOOP_IMR
) = 0x0000; // 18
43 SCOOP_REG(sdev
->base
,SCOOP_IRM
) = 0x00FF; // 14
44 SCOOP_REG(sdev
->base
,SCOOP_ISR
) = 0x0000; // 1C
45 SCOOP_REG(sdev
->base
,SCOOP_IRM
) = 0x0000;
48 unsigned short set_scoop_gpio(struct device
*dev
, unsigned short bit
)
50 unsigned short gpio_bit
;
52 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
54 spin_lock_irqsave(&sdev
->scoop_lock
, flag
);
55 gpio_bit
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
) | bit
;
56 SCOOP_REG(sdev
->base
, SCOOP_GPWR
) = gpio_bit
;
57 spin_unlock_irqrestore(&sdev
->scoop_lock
, flag
);
62 unsigned short reset_scoop_gpio(struct device
*dev
, unsigned short bit
)
64 unsigned short gpio_bit
;
66 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
68 spin_lock_irqsave(&sdev
->scoop_lock
, flag
);
69 gpio_bit
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
) & ~bit
;
70 SCOOP_REG(sdev
->base
,SCOOP_GPWR
) = gpio_bit
;
71 spin_unlock_irqrestore(&sdev
->scoop_lock
, flag
);
76 EXPORT_SYMBOL(set_scoop_gpio
);
77 EXPORT_SYMBOL(reset_scoop_gpio
);
79 unsigned short read_scoop_reg(struct device
*dev
, unsigned short reg
)
81 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
82 return SCOOP_REG(sdev
->base
,reg
);
85 void write_scoop_reg(struct device
*dev
, unsigned short reg
, unsigned short data
)
87 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
88 SCOOP_REG(sdev
->base
,reg
)=data
;
91 EXPORT_SYMBOL(reset_scoop
);
92 EXPORT_SYMBOL(read_scoop_reg
);
93 EXPORT_SYMBOL(write_scoop_reg
);
95 static void check_scoop_reg(struct scoop_dev
*sdev
)
99 mcr
= SCOOP_REG(sdev
->base
, SCOOP_MCR
);
100 if ((mcr
& 0x100) == 0)
101 SCOOP_REG(sdev
->base
, SCOOP_MCR
) = 0x0101;
105 static int scoop_suspend(struct device
*dev
, pm_message_t state
)
107 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
109 check_scoop_reg(sdev
);
110 sdev
->scoop_gpwr
= SCOOP_REG(sdev
->base
, SCOOP_GPWR
);
111 SCOOP_REG(sdev
->base
, SCOOP_GPWR
) = (sdev
->scoop_gpwr
& ~sdev
->suspend_clr
) | sdev
->suspend_set
;
116 static int scoop_resume(struct device
*dev
)
118 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
120 check_scoop_reg(sdev
);
121 SCOOP_REG(sdev
->base
,SCOOP_GPWR
) = sdev
->scoop_gpwr
;
126 #define scoop_suspend NULL
127 #define scoop_resume NULL
130 int __init
scoop_probe(struct device
*dev
)
132 struct scoop_dev
*devptr
;
133 struct scoop_config
*inf
;
134 struct platform_device
*pdev
= to_platform_device(dev
);
135 struct resource
*mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
140 devptr
= kmalloc(sizeof(struct scoop_dev
), GFP_KERNEL
);
145 memset(devptr
, 0, sizeof(struct scoop_dev
));
146 spin_lock_init(&devptr
->scoop_lock
);
148 inf
= dev
->platform_data
;
149 devptr
->base
= ioremap(mem
->start
, mem
->end
- mem
->start
+ 1);
156 dev_set_drvdata(dev
, devptr
);
158 printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem
->start
,(unsigned int)devptr
->base
);
160 SCOOP_REG(devptr
->base
, SCOOP_MCR
) = 0x0140;
162 SCOOP_REG(devptr
->base
, SCOOP_GPCR
) = inf
->io_dir
& 0xffff;
163 SCOOP_REG(devptr
->base
, SCOOP_GPWR
) = inf
->io_out
& 0xffff;
165 devptr
->suspend_clr
= inf
->suspend_clr
;
166 devptr
->suspend_set
= inf
->suspend_set
;
171 static int scoop_remove(struct device
*dev
)
173 struct scoop_dev
*sdev
= dev_get_drvdata(dev
);
177 dev_set_drvdata(dev
, NULL
);
182 static struct device_driver scoop_driver
= {
183 .name
= "sharp-scoop",
184 .bus
= &platform_bus_type
,
185 .probe
= scoop_probe
,
186 .remove
= scoop_remove
,
187 .suspend
= scoop_suspend
,
188 .resume
= scoop_resume
,
191 int __init
scoop_init(void)
193 return driver_register(&scoop_driver
);
196 subsys_initcall(scoop_init
);