diff options
Diffstat (limited to 'drivers/spi/spi_butterfly.c')
-rw-r--r-- | drivers/spi/spi_butterfly.c | 83 |
1 files changed, 8 insertions, 75 deletions
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index 312987a03210..0ee2b2090252 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/parport.h> | 24 | #include <linux/parport.h> |
25 | 25 | ||
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
@@ -40,8 +40,6 @@ | |||
40 | * and use this custom parallel port cable. | 40 | * and use this custom parallel port cable. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #undef HAVE_USI /* nyet */ | ||
44 | |||
45 | 43 | ||
46 | /* DATA output bits (pins 2..9 == D0..D7) */ | 44 | /* DATA output bits (pins 2..9 == D0..D7) */ |
47 | #define butterfly_nreset (1 << 1) /* pin 3 */ | 45 | #define butterfly_nreset (1 << 1) /* pin 3 */ |
@@ -49,19 +47,13 @@ | |||
49 | #define spi_sck_bit (1 << 0) /* pin 2 */ | 47 | #define spi_sck_bit (1 << 0) /* pin 2 */ |
50 | #define spi_mosi_bit (1 << 7) /* pin 9 */ | 48 | #define spi_mosi_bit (1 << 7) /* pin 9 */ |
51 | 49 | ||
52 | #define usi_sck_bit (1 << 3) /* pin 5 */ | ||
53 | #define usi_mosi_bit (1 << 4) /* pin 6 */ | ||
54 | |||
55 | #define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */ | 50 | #define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */ |
56 | 51 | ||
57 | /* STATUS input bits */ | 52 | /* STATUS input bits */ |
58 | #define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */ | 53 | #define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */ |
59 | 54 | ||
60 | #define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */ | ||
61 | |||
62 | /* CONTROL output bits */ | 55 | /* CONTROL output bits */ |
63 | #define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ | 56 | #define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ |
64 | /* USI uses no chipselect */ | ||
65 | 57 | ||
66 | 58 | ||
67 | 59 | ||
@@ -70,15 +62,6 @@ static inline struct butterfly *spidev_to_pp(struct spi_device *spi) | |||
70 | return spi->controller_data; | 62 | return spi->controller_data; |
71 | } | 63 | } |
72 | 64 | ||
73 | static inline int is_usidev(struct spi_device *spi) | ||
74 | { | ||
75 | #ifdef HAVE_USI | ||
76 | return spi->chip_select != 1; | ||
77 | #else | ||
78 | return 0; | ||
79 | #endif | ||
80 | } | ||
81 | |||
82 | 65 | ||
83 | struct butterfly { | 66 | struct butterfly { |
84 | /* REVISIT ... for now, this must be first */ | 67 | /* REVISIT ... for now, this must be first */ |
@@ -97,23 +80,13 @@ struct butterfly { | |||
97 | 80 | ||
98 | /*----------------------------------------------------------------------*/ | 81 | /*----------------------------------------------------------------------*/ |
99 | 82 | ||
100 | /* | ||
101 | * these routines may be slower than necessary because they're hiding | ||
102 | * the fact that there are two different SPI busses on this cable: one | ||
103 | * to the DataFlash chip (or AVR SPI controller), the other to the | ||
104 | * AVR USI controller. | ||
105 | */ | ||
106 | |||
107 | static inline void | 83 | static inline void |
108 | setsck(struct spi_device *spi, int is_on) | 84 | setsck(struct spi_device *spi, int is_on) |
109 | { | 85 | { |
110 | struct butterfly *pp = spidev_to_pp(spi); | 86 | struct butterfly *pp = spidev_to_pp(spi); |
111 | u8 bit, byte = pp->lastbyte; | 87 | u8 bit, byte = pp->lastbyte; |
112 | 88 | ||
113 | if (is_usidev(spi)) | 89 | bit = spi_sck_bit; |
114 | bit = usi_sck_bit; | ||
115 | else | ||
116 | bit = spi_sck_bit; | ||
117 | 90 | ||
118 | if (is_on) | 91 | if (is_on) |
119 | byte |= bit; | 92 | byte |= bit; |
@@ -129,10 +102,7 @@ setmosi(struct spi_device *spi, int is_on) | |||
129 | struct butterfly *pp = spidev_to_pp(spi); | 102 | struct butterfly *pp = spidev_to_pp(spi); |
130 | u8 bit, byte = pp->lastbyte; | 103 | u8 bit, byte = pp->lastbyte; |
131 | 104 | ||
132 | if (is_usidev(spi)) | 105 | bit = spi_mosi_bit; |
133 | bit = usi_mosi_bit; | ||
134 | else | ||
135 | bit = spi_mosi_bit; | ||
136 | 106 | ||
137 | if (is_on) | 107 | if (is_on) |
138 | byte |= bit; | 108 | byte |= bit; |
@@ -148,10 +118,7 @@ static inline int getmiso(struct spi_device *spi) | |||
148 | int value; | 118 | int value; |
149 | u8 bit; | 119 | u8 bit; |
150 | 120 | ||
151 | if (is_usidev(spi)) | 121 | bit = spi_miso_bit; |
152 | bit = usi_miso_bit; | ||
153 | else | ||
154 | bit = spi_miso_bit; | ||
155 | 122 | ||
156 | /* only STATUS_BUSY is NOT negated */ | 123 | /* only STATUS_BUSY is NOT negated */ |
157 | value = !(parport_read_status(pp->port) & bit); | 124 | value = !(parport_read_status(pp->port) & bit); |
@@ -166,10 +133,6 @@ static void butterfly_chipselect(struct spi_device *spi, int value) | |||
166 | if (value != BITBANG_CS_INACTIVE) | 133 | if (value != BITBANG_CS_INACTIVE) |
167 | setsck(spi, spi->mode & SPI_CPOL); | 134 | setsck(spi, spi->mode & SPI_CPOL); |
168 | 135 | ||
169 | /* no chipselect on this USI link config */ | ||
170 | if (is_usidev(spi)) | ||
171 | return; | ||
172 | |||
173 | /* here, value == "activate or not"; | 136 | /* here, value == "activate or not"; |
174 | * most PARPORT_CONTROL_* bits are negated, so we must | 137 | * most PARPORT_CONTROL_* bits are negated, so we must |
175 | * morph it to value == "bit value to write in control register" | 138 | * morph it to value == "bit value to write in control register" |
@@ -237,24 +200,16 @@ static void butterfly_attach(struct parport *p) | |||
237 | int status; | 200 | int status; |
238 | struct butterfly *pp; | 201 | struct butterfly *pp; |
239 | struct spi_master *master; | 202 | struct spi_master *master; |
240 | struct platform_device *pdev; | 203 | struct device *dev = p->physport->dev; |
241 | 204 | ||
242 | if (butterfly) | 205 | if (butterfly || !dev) |
243 | return; | 206 | return; |
244 | 207 | ||
245 | /* REVISIT: this just _assumes_ a butterfly is there ... no probe, | 208 | /* REVISIT: this just _assumes_ a butterfly is there ... no probe, |
246 | * and no way to be selective about what it binds to. | 209 | * and no way to be selective about what it binds to. |
247 | */ | 210 | */ |
248 | 211 | ||
249 | /* FIXME where should master->cdev.dev come from? | 212 | master = spi_alloc_master(dev, sizeof *pp); |
250 | * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc | ||
251 | * setting up a platform device like this is an ugly kluge... | ||
252 | */ | ||
253 | pdev = platform_device_register_simple("butterfly", -1, NULL, 0); | ||
254 | if (IS_ERR(pdev)) | ||
255 | return; | ||
256 | |||
257 | master = spi_alloc_master(&pdev->dev, sizeof *pp); | ||
258 | if (!master) { | 213 | if (!master) { |
259 | status = -ENOMEM; | 214 | status = -ENOMEM; |
260 | goto done; | 215 | goto done; |
@@ -300,7 +255,7 @@ static void butterfly_attach(struct parport *p) | |||
300 | parport_frob_control(pp->port, spi_cs_bit, 0); | 255 | parport_frob_control(pp->port, spi_cs_bit, 0); |
301 | 256 | ||
302 | /* stabilize power with chip in reset (nRESET), and | 257 | /* stabilize power with chip in reset (nRESET), and |
303 | * both spi_sck_bit and usi_sck_bit clear (CPOL=0) | 258 | * spi_sck_bit clear (CPOL=0) |
304 | */ | 259 | */ |
305 | pp->lastbyte |= vcc_bits; | 260 | pp->lastbyte |= vcc_bits; |
306 | parport_write_data(pp->port, pp->lastbyte); | 261 | parport_write_data(pp->port, pp->lastbyte); |
@@ -334,23 +289,6 @@ static void butterfly_attach(struct parport *p) | |||
334 | pr_debug("%s: dataflash at %s\n", p->name, | 289 | pr_debug("%s: dataflash at %s\n", p->name, |
335 | pp->dataflash->dev.bus_id); | 290 | pp->dataflash->dev.bus_id); |
336 | 291 | ||
337 | #ifdef HAVE_USI | ||
338 | /* Bus 2 is only for talking to the AVR, and it can work no | ||
339 | * matter who masters bus 1; needs appropriate AVR firmware. | ||
340 | */ | ||
341 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; | ||
342 | strcpy(pp->info[1].modalias, "butterfly"); | ||
343 | // pp->info[1].platform_data = ... TBD ... ; | ||
344 | pp->info[1].chip_select = 2, | ||
345 | pp->info[1].controller_data = pp; | ||
346 | pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]); | ||
347 | if (pp->butterfly) | ||
348 | pr_debug("%s: butterfly at %s\n", p->name, | ||
349 | pp->butterfly->dev.bus_id); | ||
350 | |||
351 | /* FIXME setup ACK for the IRQ line ... */ | ||
352 | #endif | ||
353 | |||
354 | // dev_info(_what?_, ...) | 292 | // dev_info(_what?_, ...) |
355 | pr_info("%s: AVR Butterfly\n", p->name); | 293 | pr_info("%s: AVR Butterfly\n", p->name); |
356 | butterfly = pp; | 294 | butterfly = pp; |
@@ -366,14 +304,12 @@ clean1: | |||
366 | clean0: | 304 | clean0: |
367 | (void) spi_master_put(pp->bitbang.master); | 305 | (void) spi_master_put(pp->bitbang.master); |
368 | done: | 306 | done: |
369 | platform_device_unregister(pdev); | ||
370 | pr_debug("%s: butterfly probe, fail %d\n", p->name, status); | 307 | pr_debug("%s: butterfly probe, fail %d\n", p->name, status); |
371 | } | 308 | } |
372 | 309 | ||
373 | static void butterfly_detach(struct parport *p) | 310 | static void butterfly_detach(struct parport *p) |
374 | { | 311 | { |
375 | struct butterfly *pp; | 312 | struct butterfly *pp; |
376 | struct platform_device *pdev; | ||
377 | int status; | 313 | int status; |
378 | 314 | ||
379 | /* FIXME this global is ugly ... but, how to quickly get from | 315 | /* FIXME this global is ugly ... but, how to quickly get from |
@@ -386,7 +322,6 @@ static void butterfly_detach(struct parport *p) | |||
386 | butterfly = NULL; | 322 | butterfly = NULL; |
387 | 323 | ||
388 | /* stop() unregisters child devices too */ | 324 | /* stop() unregisters child devices too */ |
389 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); | ||
390 | status = spi_bitbang_stop(&pp->bitbang); | 325 | status = spi_bitbang_stop(&pp->bitbang); |
391 | 326 | ||
392 | /* turn off VCC */ | 327 | /* turn off VCC */ |
@@ -397,8 +332,6 @@ static void butterfly_detach(struct parport *p) | |||
397 | parport_unregister_device(pp->pd); | 332 | parport_unregister_device(pp->pd); |
398 | 333 | ||
399 | (void) spi_master_put(pp->bitbang.master); | 334 | (void) spi_master_put(pp->bitbang.master); |
400 | |||
401 | platform_device_unregister(pdev); | ||
402 | } | 335 | } |
403 | 336 | ||
404 | static struct parport_driver butterfly_driver = { | 337 | static struct parport_driver butterfly_driver = { |