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"); |
