aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKristoffer Ericson <Kristoffer_e1@hotmail.com>2007-07-20 13:22:57 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-07-20 16:33:19 -0400
commit69ebb22277a53f612ccd632ceb73ed87c9093412 (patch)
treecb3d573e74f1d5faf877e116b7e4e77b02540917 /arch
parent7b4c965a0b74748269d05185a394c9dc121dd558 (diff)
[ARM] 4506/1: HP Jornada 7XX: Addition of SSP Platform Driver
These patches add full SSP/MCU support for the HP Jornada 720 machine. Its needed to handle keyboard, touchscreen, battery and backlight/lcd. The main driver exports functions and the header file exports the command values. When talking to the MCU the general procedure is to start MCU, send command (using ssp_inout(command)), the proper reply is always TXDUMMY. After receiving TXDUMMY you can send the value you wish pushed (for example brightness level). End with ssp_end() so the spinlock gets unlocked. Drivers using this havent been implemented yet, but will shortly. Signed-off-by: Kristoffer Ericson <Kristoffer.ericson@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-sa1100/Kconfig13
-rw-r--r--arch/arm/mach-sa1100/Makefile2
-rw-r--r--arch/arm/mach-sa1100/jornada720_ssp.c201
3 files changed, 214 insertions, 2 deletions
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index cd67ab1b217b..f99d9013905f 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -101,6 +101,16 @@ config SA1100_JORNADA720
101 handheld computer. See <http://www.hp.com/jornada/products/720> 101 handheld computer. See <http://www.hp.com/jornada/products/720>
102 for details. 102 for details.
103 103
104config SA1100_JORNADA720_SSP
105 bool "HP Jornada 720 Extended SSP driver"
106 select SA1100_SSP
107 depends on SA1100_JORNADA720
108 help
109 Say Y here if you have a HP Jornada 7xx handheld computer and you
110 want to access devices connected to the MCU. Those include the
111 keyboard, touchscreen, backlight and battery. This driver also activates
112 the generic SSP which it extends.
113
104config SA1100_HACKKIT 114config SA1100_HACKKIT
105 bool "HackKit Core CPU Board" 115 bool "HackKit Core CPU Board"
106 help 116 help
@@ -145,8 +155,7 @@ config SA1100_SSP
145 help 155 help
146 Say Y here to enable support for the generic PIO SSP driver. 156 Say Y here to enable support for the generic PIO SSP driver.
147 This isn't for audio support, but for attached sensors and 157 This isn't for audio support, but for attached sensors and
148 other devices, eg for BadgePAD 4 sensor support, or Jornada 158 other devices, eg for BadgePAD 4 sensor support.
149 720 touchscreen support.
150 159
151config H3600_SLEEVE 160config H3600_SLEEVE
152 tristate "Compaq iPAQ Handheld sleeve support" 161 tristate "Compaq iPAQ Handheld sleeve support"
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index e27f15042a22..7a61e8d33ab7 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
31led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o 31led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o
32 32
33obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o 33obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
34obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o
34 35
35obj-$(CONFIG_SA1100_LART) += lart.o 36obj-$(CONFIG_SA1100_LART) += lart.o
36led-$(CONFIG_SA1100_LART) += leds-lart.o 37led-$(CONFIG_SA1100_LART) += leds-lart.o
@@ -51,3 +52,4 @@ obj-$(CONFIG_LEDS) += $(led-y)
51# Miscelaneous functions 52# Miscelaneous functions
52obj-$(CONFIG_PM) += pm.o sleep.o 53obj-$(CONFIG_PM) += pm.o sleep.o
53obj-$(CONFIG_SA1100_SSP) += ssp.o 54obj-$(CONFIG_SA1100_SSP) += ssp.o
55
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c
new file mode 100644
index 000000000000..0a45e1ac8ad6
--- /dev/null
+++ b/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -0,0 +1,201 @@
1/**
2 * arch/arm/mac-sa1100/jornada720_ssp.c
3 *
4 * Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
5 * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * SSP driver for the HP Jornada 710/720/728
12 */
13
14#include <linux/delay.h>
15#include <linux/errno.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/sched.h>
21#include <linux/slab.h>
22
23#include <asm/hardware.h>
24#include <asm/hardware/ssp.h>
25#include <asm/arch/jornada720.h>
26
27static DEFINE_SPINLOCK(jornada_ssp_lock);
28static unsigned long jornada_ssp_flags;
29
30/**
31 * jornada_ssp_reverse - reverses input byte
32 *
33 * we need to reverse all data we recieve from the mcu due to its physical location
34 * returns : 01110111 -> 11101110
35 */
36u8 inline jornada_ssp_reverse(u8 byte)
37{
38 return
39 ((0x80 & byte) >> 7) |
40 ((0x40 & byte) >> 5) |
41 ((0x20 & byte) >> 3) |
42 ((0x10 & byte) >> 1) |
43 ((0x08 & byte) << 1) |
44 ((0x04 & byte) << 3) |
45 ((0x02 & byte) << 5) |
46 ((0x01 & byte) << 7);
47};
48EXPORT_SYMBOL(jornada_ssp_reverse);
49
50/**
51 * jornada_ssp_byte - waits for ready ssp bus and sends byte
52 *
53 * waits for fifo buffer to clear and then transmits, if it doesn't then we will
54 * timeout after <timeout> rounds. Needs mcu running before its called.
55 *
56 * returns : %mcu output on success
57 * : %-ETIMEOUT on timeout
58 */
59int jornada_ssp_byte(u8 byte)
60{
61 int timeout = 400000;
62 u16 ret;
63
64 while ((GPLR & GPIO_GPIO10)) {
65 if (!--timeout) {
66 printk(KERN_WARNING "SSP: timeout while waiting for transmit\n");
67 return -ETIMEDOUT;
68 }
69 cpu_relax();
70 }
71
72 ret = jornada_ssp_reverse(byte) << 8;
73
74 ssp_write_word(ret);
75 ssp_read_word(&ret);
76
77 return jornada_ssp_reverse(ret);
78};
79EXPORT_SYMBOL(jornada_ssp_byte);
80
81/**
82 * jornada_ssp_inout - decide if input is command or trading byte
83 *
84 * returns : (jornada_ssp_byte(byte)) on success
85 * : %-ETIMEOUT on timeout failure
86 */
87int jornada_ssp_inout(u8 byte)
88{
89 int ret, i;
90
91 /* true means command byte */
92 if (byte != TXDUMMY) {
93 ret = jornada_ssp_byte(byte);
94 /* Proper return to commands is TxDummy */
95 if (ret != TXDUMMY) {
96 for (i = 0; i < 256; i++)/* flushing bus */
97 if (jornada_ssp_byte(TXDUMMY) == -1)
98 break;
99 return -ETIMEDOUT;
100 }
101 } else /* Exchange TxDummy for data */
102 ret = jornada_ssp_byte(TXDUMMY);
103
104 return ret;
105};
106EXPORT_SYMBOL(jornada_ssp_inout);
107
108/**
109 * jornada_ssp_start - enable mcu
110 *
111 */
112int jornada_ssp_start()
113{
114 spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags);
115 GPCR = GPIO_GPIO25;
116 udelay(50);
117 return 0;
118};
119EXPORT_SYMBOL(jornada_ssp_start);
120
121/**
122 * jornada_ssp_end - disable mcu and turn off lock
123 *
124 */
125int jornada_ssp_end()
126{
127 GPSR = GPIO_GPIO25;
128 spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags);
129 return 0;
130};
131EXPORT_SYMBOL(jornada_ssp_end);
132
133static int __init jornada_ssp_probe(struct platform_device *dev)
134{
135 int ret;
136
137 GPSR = GPIO_GPIO25;
138
139 ret = ssp_init();
140
141 /* worked fine, lets not bother with anything else */
142 if (!ret) {
143 printk(KERN_INFO "SSP: device initialized with irq\n");
144 return ret;
145 }
146
147 printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution \n");
148
149 /* init of Serial 4 port */
150 Ser4MCCR0 = 0;
151 Ser4SSCR0 = 0x0387;
152 Ser4SSCR1 = 0x18;
153
154 /* clear out any left over data */
155 ssp_flush();
156
157 /* enable MCU */
158 jornada_ssp_start();
159
160 /* see if return value makes sense */
161 ret = jornada_ssp_inout(GETBRIGHTNESS);
162
163 /* seems like it worked, just feed it with TxDummy to get rid of data */
164 if (ret == TxDummy)
165 jornada_ssp_inout(TXDUMMY);
166
167 jornada_ssp_end();
168
169 /* failed, lets just kill everything */
170 if (ret == -ETIMEDOUT) {
171 printk(KERN_WARNING "SSP: attempts failed, bailing\n");
172 ssp_exit();
173 return -ENODEV;
174 }
175
176 /* all fine */
177 printk(KERN_INFO "SSP: device initialized\n");
178 return 0;
179};
180
181static int jornada_ssp_remove(struct platform_device *dev)
182{
183 /* Note that this doesnt actually remove the driver, since theres nothing to remove
184 * It just makes sure everything is turned off */
185 GPSR = GPIO_GPIO25;
186 ssp_exit();
187 return 0;
188};
189
190struct platform_driver jornadassp_driver = {
191 .probe = jornada_ssp_probe,
192 .remove = jornada_ssp_remove,
193 .driver = {
194 .name = "jornada_ssp",
195 },
196};
197
198static int __init jornada_ssp_init(void)
199{
200 return platform_driver_register(&jornadassp_driver);
201}