[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>

authored by Kristoffer Ericson and committed by Russell King 69ebb222 7b4c965a

+241 -2
+11 -2
arch/arm/mach-sa1100/Kconfig
··· 101 101 handheld computer. See <http://www.hp.com/jornada/products/720> 102 102 for details. 103 103 104 + config 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 + 104 114 config SA1100_HACKKIT 105 115 bool "HackKit Core CPU Board" 106 116 help ··· 155 145 help 156 146 Say Y here to enable support for the generic PIO SSP driver. 157 147 This isn't for audio support, but for attached sensors and 158 - other devices, eg for BadgePAD 4 sensor support, or Jornada 159 - 720 touchscreen support. 148 + other devices, eg for BadgePAD 4 sensor support. 160 149 161 150 config H3600_SLEEVE 162 151 tristate "Compaq iPAQ Handheld sleeve support"
+2
arch/arm/mach-sa1100/Makefile
··· 31 31 led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o 32 32 33 33 obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o 34 + obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o 34 35 35 36 obj-$(CONFIG_SA1100_LART) += lart.o 36 37 led-$(CONFIG_SA1100_LART) += leds-lart.o ··· 52 51 # Miscelaneous functions 53 52 obj-$(CONFIG_PM) += pm.o sleep.o 54 53 obj-$(CONFIG_SA1100_SSP) += ssp.o 54 +
+201
arch/arm/mach-sa1100/jornada720_ssp.c
··· 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 + 27 + static DEFINE_SPINLOCK(jornada_ssp_lock); 28 + static 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 + */ 36 + u8 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 + }; 48 + EXPORT_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 + */ 59 + int 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 + }; 79 + EXPORT_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 + */ 87 + int 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 + }; 106 + EXPORT_SYMBOL(jornada_ssp_inout); 107 + 108 + /** 109 + * jornada_ssp_start - enable mcu 110 + * 111 + */ 112 + int 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 + }; 119 + EXPORT_SYMBOL(jornada_ssp_start); 120 + 121 + /** 122 + * jornada_ssp_end - disable mcu and turn off lock 123 + * 124 + */ 125 + int jornada_ssp_end() 126 + { 127 + GPSR = GPIO_GPIO25; 128 + spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags); 129 + return 0; 130 + }; 131 + EXPORT_SYMBOL(jornada_ssp_end); 132 + 133 + static 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 + 181 + static 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 + 190 + struct platform_driver jornadassp_driver = { 191 + .probe = jornada_ssp_probe, 192 + .remove = jornada_ssp_remove, 193 + .driver = { 194 + .name = "jornada_ssp", 195 + }, 196 + }; 197 + 198 + static int __init jornada_ssp_init(void) 199 + { 200 + return platform_driver_register(&jornadassp_driver); 201 + }
+27
include/asm-arm/arch-sa1100/jornada720.h
··· 1 + /* 2 + * include/asm-arm/arch-sa1100/jornada720.h 3 + * 4 + * This file contains SSP/MCU communication definitions for HP Jornada 710/720/728 5 + * 6 + * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com> 7 + * Copyright (C) 2000 John Ankcorn <jca@lcs.mit.edu> 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + * 13 + */ 14 + 15 + /* HP Jornada 7xx microprocessor commands */ 16 + #define GETBATTERYDATA 0xc0 17 + #define GETSCANKEYCODE 0x90 18 + #define GETTOUCHSAMPLES 0xa0 19 + #define GETCONTRAST 0xD0 20 + #define SETCONTRAST 0xD1 21 + #define GETBRIGHTNESS 0xD2 22 + #define SETBRIGHTNESS 0xD3 23 + #define CONTRASTOFF 0xD8 24 + #define BRIGHTNESSOFF 0xD9 25 + #define PWMOFF 0xDF 26 + #define TXDUMMY 0x11 27 + #define ERRORCODE 0x00