diff options
-rw-r--r-- | Documentation/spi/butterfly | 23 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/spi/spi_butterfly.c | 36 |
3 files changed, 34 insertions, 35 deletions
diff --git a/Documentation/spi/butterfly b/Documentation/spi/butterfly index a2e8c8d90e35..9927af7a629c 100644 --- a/Documentation/spi/butterfly +++ b/Documentation/spi/butterfly | |||
@@ -12,13 +12,20 @@ You can make this adapter from an old printer cable and solder things | |||
12 | directly to the Butterfly. Or (if you have the parts and skills) you | 12 | directly to the Butterfly. Or (if you have the parts and skills) you |
13 | can come up with something fancier, providing ciruit protection to the | 13 | can come up with something fancier, providing ciruit protection to the |
14 | Butterfly and the printer port, or with a better power supply than two | 14 | Butterfly and the printer port, or with a better power supply than two |
15 | signal pins from the printer port. | 15 | signal pins from the printer port. Or for that matter, you can use |
16 | similar cables to talk to many AVR boards, even a breadboard. | ||
17 | |||
18 | This is more powerful than "ISP programming" cables since it lets kernel | ||
19 | SPI protocol drivers interact with the AVR, and could even let the AVR | ||
20 | issue interrupts to them. Later, your protocol driver should work | ||
21 | easily with a "real SPI controller", instead of this bitbanger. | ||
16 | 22 | ||
17 | 23 | ||
18 | The first cable connections will hook Linux up to one SPI bus, with the | 24 | The first cable connections will hook Linux up to one SPI bus, with the |
19 | AVR and a DataFlash chip; and to the AVR reset line. This is all you | 25 | AVR and a DataFlash chip; and to the AVR reset line. This is all you |
20 | need to reflash the firmware, and the pins are the standard Atmel "ISP" | 26 | need to reflash the firmware, and the pins are the standard Atmel "ISP" |
21 | connector pins (used also on non-Butterfly AVR boards). | 27 | connector pins (used also on non-Butterfly AVR boards). On the parport |
28 | side this is like "sp12" programming cables. | ||
22 | 29 | ||
23 | Signal Butterfly Parport (DB-25) | 30 | Signal Butterfly Parport (DB-25) |
24 | ------ --------- --------------- | 31 | ------ --------- --------------- |
@@ -40,10 +47,14 @@ by clearing PORTB.[0-3]); (b) configure the mtd_dataflash driver; and | |||
40 | SELECT = J400.PB0/nSS = pin 17/C3,nSELECT | 47 | SELECT = J400.PB0/nSS = pin 17/C3,nSELECT |
41 | GND = J400.GND = pin 24/GND | 48 | GND = J400.GND = pin 24/GND |
42 | 49 | ||
43 | The "USI" controller, using J405, can be used for a second SPI bus. That | 50 | Or you could flash firmware making the AVR into an SPI slave (keeping the |
44 | would let you talk to the AVR over SPI, running firmware that makes it act | 51 | DataFlash in reset) and tweak the spi_butterfly driver to make it bind to |
45 | as an SPI slave, while letting either Linux or the AVR use the DataFlash. | 52 | the driver for your custom SPI-based protocol. |
46 | There are plenty of spare parport pins to wire this one up, such as: | 53 | |
54 | The "USI" controller, using J405, can also be used for a second SPI bus. | ||
55 | That would let you talk to the AVR using custom SPI-with-USI firmware, | ||
56 | while letting either Linux or the AVR use the DataFlash. There are plenty | ||
57 | of spare parport pins to wire this one up, such as: | ||
47 | 58 | ||
48 | Signal Butterfly Parport (DB-25) | 59 | Signal Butterfly Parport (DB-25) |
49 | ------ --------- --------------- | 60 | ------ --------- --------------- |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b77dbd63e596..7a75faeb0526 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -75,16 +75,6 @@ config SPI_BUTTERFLY | |||
75 | inexpensive battery powered microcontroller evaluation board. | 75 | inexpensive battery powered microcontroller evaluation board. |
76 | This same cable can be used to flash new firmware. | 76 | This same cable can be used to flash new firmware. |
77 | 77 | ||
78 | config SPI_BUTTERFLY | ||
79 | tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" | ||
80 | depends on SPI_MASTER && PARPORT && EXPERIMENTAL | ||
81 | select SPI_BITBANG | ||
82 | help | ||
83 | This uses a custom parallel port cable to connect to an AVR | ||
84 | Butterfly <http://www.atmel.com/products/avr/butterfly>, an | ||
85 | inexpensive battery powered microcontroller evaluation board. | ||
86 | This same cable can be used to flash new firmware. | ||
87 | |||
88 | # | 78 | # |
89 | # Add new SPI master controllers in alphabetical order above this line | 79 | # Add new SPI master controllers in alphabetical order above this line |
90 | # | 80 | # |
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index 79a3c59615ab..ff9e5faa4dc9 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c | |||
@@ -163,21 +163,20 @@ static void butterfly_chipselect(struct spi_device *spi, int value) | |||
163 | struct butterfly *pp = spidev_to_pp(spi); | 163 | struct butterfly *pp = spidev_to_pp(spi); |
164 | 164 | ||
165 | /* set default clock polarity */ | 165 | /* set default clock polarity */ |
166 | if (value) | 166 | if (value != BITBANG_CS_INACTIVE) |
167 | setsck(spi, spi->mode & SPI_CPOL); | 167 | setsck(spi, spi->mode & SPI_CPOL); |
168 | 168 | ||
169 | /* no chipselect on this USI link config */ | 169 | /* no chipselect on this USI link config */ |
170 | if (is_usidev(spi)) | 170 | if (is_usidev(spi)) |
171 | return; | 171 | return; |
172 | 172 | ||
173 | /* here, value == "activate or not" */ | 173 | /* here, value == "activate or not"; |
174 | 174 | * most PARPORT_CONTROL_* bits are negated, so we must | |
175 | /* most PARPORT_CONTROL_* bits are negated */ | 175 | * morph it to value == "bit value to write in control register" |
176 | */ | ||
176 | if (spi_cs_bit == PARPORT_CONTROL_INIT) | 177 | if (spi_cs_bit == PARPORT_CONTROL_INIT) |
177 | value = !value; | 178 | value = !value; |
178 | 179 | ||
179 | /* here, value == "bit value to write in control register" */ | ||
180 | |||
181 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); | 180 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); |
182 | } | 181 | } |
183 | 182 | ||
@@ -202,7 +201,9 @@ butterfly_txrx_word_mode0(struct spi_device *spi, | |||
202 | 201 | ||
203 | /* override default partitioning with cmdlinepart */ | 202 | /* override default partitioning with cmdlinepart */ |
204 | static struct mtd_partition partitions[] = { { | 203 | static struct mtd_partition partitions[] = { { |
205 | /* JFFS2 wants partitions of 4*N blocks for this device ... */ | 204 | /* JFFS2 wants partitions of 4*N blocks for this device, |
205 | * so sectors 0 and 1 can't be partitions by themselves. | ||
206 | */ | ||
206 | 207 | ||
207 | /* sector 0 = 8 pages * 264 bytes/page (1 block) | 208 | /* sector 0 = 8 pages * 264 bytes/page (1 block) |
208 | * sector 1 = 248 pages * 264 bytes/page | 209 | * sector 1 = 248 pages * 264 bytes/page |
@@ -316,8 +317,9 @@ static void butterfly_attach(struct parport *p) | |||
316 | if (status < 0) | 317 | if (status < 0) |
317 | goto clean2; | 318 | goto clean2; |
318 | 319 | ||
319 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR) | 320 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR |
320 | * or AVR (firmware resets at45, acts as spi slave) | 321 | * (firmware resets at45, acts as spi slave) or neither (we ignore |
322 | * both, AVR uses AT45). Here we expect firmware for the first option. | ||
321 | */ | 323 | */ |
322 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; | 324 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; |
323 | strcpy(pp->info[0].modalias, "mtd_dataflash"); | 325 | strcpy(pp->info[0].modalias, "mtd_dataflash"); |
@@ -330,7 +332,9 @@ static void butterfly_attach(struct parport *p) | |||
330 | pp->dataflash->dev.bus_id); | 332 | pp->dataflash->dev.bus_id); |
331 | 333 | ||
332 | #ifdef HAVE_USI | 334 | #ifdef HAVE_USI |
333 | /* even more custom AVR firmware */ | 335 | /* Bus 2 is only for talking to the AVR, and it can work no |
336 | * matter who masters bus 1; needs appropriate AVR firmware. | ||
337 | */ | ||
334 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; | 338 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; |
335 | strcpy(pp->info[1].modalias, "butterfly"); | 339 | strcpy(pp->info[1].modalias, "butterfly"); |
336 | // pp->info[1].platform_data = ... TBD ... ; | 340 | // pp->info[1].platform_data = ... TBD ... ; |
@@ -378,13 +382,8 @@ static void butterfly_detach(struct parport *p) | |||
378 | pp = butterfly; | 382 | pp = butterfly; |
379 | butterfly = NULL; | 383 | butterfly = NULL; |
380 | 384 | ||
381 | #ifdef HAVE_USI | 385 | /* stop() unregisters child devices too */ |
382 | spi_unregister_device(pp->butterfly); | 386 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); |
383 | pp->butterfly = NULL; | ||
384 | #endif | ||
385 | spi_unregister_device(pp->dataflash); | ||
386 | pp->dataflash = NULL; | ||
387 | |||
388 | status = spi_bitbang_stop(&pp->bitbang); | 387 | status = spi_bitbang_stop(&pp->bitbang); |
389 | 388 | ||
390 | /* turn off VCC */ | 389 | /* turn off VCC */ |
@@ -394,8 +393,6 @@ static void butterfly_detach(struct parport *p) | |||
394 | parport_release(pp->pd); | 393 | parport_release(pp->pd); |
395 | parport_unregister_device(pp->pd); | 394 | parport_unregister_device(pp->pd); |
396 | 395 | ||
397 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); | ||
398 | |||
399 | (void) spi_master_put(pp->bitbang.master); | 396 | (void) spi_master_put(pp->bitbang.master); |
400 | 397 | ||
401 | platform_device_unregister(pdev); | 398 | platform_device_unregister(pdev); |
@@ -420,4 +417,5 @@ static void __exit butterfly_exit(void) | |||
420 | } | 417 | } |
421 | module_exit(butterfly_exit); | 418 | module_exit(butterfly_exit); |
422 | 419 | ||
420 | MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly"); | ||
423 | MODULE_LICENSE("GPL"); | 421 | MODULE_LICENSE("GPL"); |