Blame view
arch/arm/mach-sa1100/jornada720_ssp.c
4.39 KB
69ebb2227 [ARM] 4506/1: HP ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/** * arch/arm/mac-sa1100/jornada720_ssp.c * * Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com> * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * SSP driver for the HP Jornada 710/720/728 */ #include <linux/delay.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/sched.h> |
69ebb2227 [ARM] 4506/1: HP ... |
21 |
|
a09e64fbc [ARM] Move includ... |
22 |
#include <mach/hardware.h> |
a09e64fbc [ARM] Move includ... |
23 |
#include <mach/jornada720.h> |
58005b325 [ARM] 5255/1: Upd... |
24 |
#include <asm/hardware/ssp.h> |
69ebb2227 [ARM] 4506/1: HP ... |
25 26 27 28 29 30 31 |
static DEFINE_SPINLOCK(jornada_ssp_lock); static unsigned long jornada_ssp_flags; /** * jornada_ssp_reverse - reverses input byte * |
25985edce Fix common misspe... |
32 |
* we need to reverse all data we receive from the mcu due to its physical location |
69ebb2227 [ARM] 4506/1: HP ... |
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
* returns : 01110111 -> 11101110 */ u8 inline jornada_ssp_reverse(u8 byte) { return ((0x80 & byte) >> 7) | ((0x40 & byte) >> 5) | ((0x20 & byte) >> 3) | ((0x10 & byte) >> 1) | ((0x08 & byte) << 1) | ((0x04 & byte) << 3) | ((0x02 & byte) << 5) | ((0x01 & byte) << 7); }; EXPORT_SYMBOL(jornada_ssp_reverse); /** * jornada_ssp_byte - waits for ready ssp bus and sends byte * * waits for fifo buffer to clear and then transmits, if it doesn't then we will * timeout after <timeout> rounds. Needs mcu running before its called. * * returns : %mcu output on success |
3ac49a1c9 trivial: fix ETIM... |
56 |
* : %-ETIMEDOUT on timeout |
69ebb2227 [ARM] 4506/1: HP ... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
*/ int jornada_ssp_byte(u8 byte) { int timeout = 400000; u16 ret; while ((GPLR & GPIO_GPIO10)) { if (!--timeout) { printk(KERN_WARNING "SSP: timeout while waiting for transmit "); return -ETIMEDOUT; } cpu_relax(); } ret = jornada_ssp_reverse(byte) << 8; ssp_write_word(ret); ssp_read_word(&ret); return jornada_ssp_reverse(ret); }; EXPORT_SYMBOL(jornada_ssp_byte); /** * jornada_ssp_inout - decide if input is command or trading byte * * returns : (jornada_ssp_byte(byte)) on success |
3ac49a1c9 trivial: fix ETIM... |
85 |
* : %-ETIMEDOUT on timeout failure |
69ebb2227 [ARM] 4506/1: HP ... |
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
*/ int jornada_ssp_inout(u8 byte) { int ret, i; /* true means command byte */ if (byte != TXDUMMY) { ret = jornada_ssp_byte(byte); /* Proper return to commands is TxDummy */ if (ret != TXDUMMY) { for (i = 0; i < 256; i++)/* flushing bus */ if (jornada_ssp_byte(TXDUMMY) == -1) break; return -ETIMEDOUT; } } else /* Exchange TxDummy for data */ ret = jornada_ssp_byte(TXDUMMY); return ret; }; EXPORT_SYMBOL(jornada_ssp_inout); /** * jornada_ssp_start - enable mcu * */ |
58005b325 [ARM] 5255/1: Upd... |
112 |
void jornada_ssp_start(void) |
69ebb2227 [ARM] 4506/1: HP ... |
113 114 115 116 |
{ spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags); GPCR = GPIO_GPIO25; udelay(50); |
58005b325 [ARM] 5255/1: Upd... |
117 |
return; |
69ebb2227 [ARM] 4506/1: HP ... |
118 119 120 121 122 123 124 |
}; EXPORT_SYMBOL(jornada_ssp_start); /** * jornada_ssp_end - disable mcu and turn off lock * */ |
58005b325 [ARM] 5255/1: Upd... |
125 |
void jornada_ssp_end(void) |
69ebb2227 [ARM] 4506/1: HP ... |
126 127 128 |
{ GPSR = GPIO_GPIO25; spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags); |
58005b325 [ARM] 5255/1: Upd... |
129 |
return; |
69ebb2227 [ARM] 4506/1: HP ... |
130 131 |
}; EXPORT_SYMBOL(jornada_ssp_end); |
91a99dfc6 platform-drivers:... |
132 |
static int __devinit jornada_ssp_probe(struct platform_device *dev) |
69ebb2227 [ARM] 4506/1: HP ... |
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
{ int ret; GPSR = GPIO_GPIO25; ret = ssp_init(); /* worked fine, lets not bother with anything else */ if (!ret) { printk(KERN_INFO "SSP: device initialized with irq "); return ret; } printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution "); /* init of Serial 4 port */ Ser4MCCR0 = 0; Ser4SSCR0 = 0x0387; Ser4SSCR1 = 0x18; /* clear out any left over data */ ssp_flush(); /* enable MCU */ jornada_ssp_start(); /* see if return value makes sense */ ret = jornada_ssp_inout(GETBRIGHTNESS); /* seems like it worked, just feed it with TxDummy to get rid of data */ |
219e3dcd1 [ARM] 4528/1: [HP... |
165 |
if (ret == TXDUMMY) |
69ebb2227 [ARM] 4506/1: HP ... |
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
jornada_ssp_inout(TXDUMMY); jornada_ssp_end(); /* failed, lets just kill everything */ if (ret == -ETIMEDOUT) { printk(KERN_WARNING "SSP: attempts failed, bailing "); ssp_exit(); return -ENODEV; } /* all fine */ printk(KERN_INFO "SSP: device initialized "); return 0; }; static int jornada_ssp_remove(struct platform_device *dev) { |
25985edce Fix common misspe... |
186 |
/* Note that this doesn't actually remove the driver, since theres nothing to remove |
69ebb2227 [ARM] 4506/1: HP ... |
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
* It just makes sure everything is turned off */ GPSR = GPIO_GPIO25; ssp_exit(); return 0; }; struct platform_driver jornadassp_driver = { .probe = jornada_ssp_probe, .remove = jornada_ssp_remove, .driver = { .name = "jornada_ssp", }, }; static int __init jornada_ssp_init(void) { return platform_driver_register(&jornadassp_driver); } |