* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/platform_device.h>
+#include <linux/device.h>
#include <linux/parport.h>
+#include <linux/sched.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/spi/flash.h>
* and use this custom parallel port cable.
*/
-#undef HAVE_USI /* nyet */
-
/* DATA output bits (pins 2..9 == D0..D7) */
#define butterfly_nreset (1 << 1) /* pin 3 */
#define spi_sck_bit (1 << 0) /* pin 2 */
#define spi_mosi_bit (1 << 7) /* pin 9 */
-#define usi_sck_bit (1 << 3) /* pin 5 */
-#define usi_mosi_bit (1 << 4) /* pin 6 */
-
#define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */
/* STATUS input bits */
#define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */
-#define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */
-
/* CONTROL output bits */
#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */
-/* USI uses no chipselect */
return spi->controller_data;
}
-static inline int is_usidev(struct spi_device *spi)
-{
-#ifdef HAVE_USI
- return spi->chip_select != 1;
-#else
- return 0;
-#endif
-}
-
struct butterfly {
/* REVISIT ... for now, this must be first */
/*----------------------------------------------------------------------*/
-/*
- * these routines may be slower than necessary because they're hiding
- * the fact that there are two different SPI busses on this cable: one
- * to the DataFlash chip (or AVR SPI controller), the other to the
- * AVR USI controller.
- */
-
static inline void
setsck(struct spi_device *spi, int is_on)
{
struct butterfly *pp = spidev_to_pp(spi);
u8 bit, byte = pp->lastbyte;
- if (is_usidev(spi))
- bit = usi_sck_bit;
- else
- bit = spi_sck_bit;
+ bit = spi_sck_bit;
if (is_on)
byte |= bit;
struct butterfly *pp = spidev_to_pp(spi);
u8 bit, byte = pp->lastbyte;
- if (is_usidev(spi))
- bit = usi_mosi_bit;
- else
- bit = spi_mosi_bit;
+ bit = spi_mosi_bit;
if (is_on)
byte |= bit;
int value;
u8 bit;
- if (is_usidev(spi))
- bit = usi_miso_bit;
- else
- bit = spi_miso_bit;
+ bit = spi_miso_bit;
/* only STATUS_BUSY is NOT negated */
value = !(parport_read_status(pp->port) & bit);
if (value != BITBANG_CS_INACTIVE)
setsck(spi, spi->mode & SPI_CPOL);
- /* no chipselect on this USI link config */
- if (is_usidev(spi))
- return;
-
/* here, value == "activate or not";
* most PARPORT_CONTROL_* bits are negated, so we must
* morph it to value == "bit value to write in control register"
int status;
struct butterfly *pp;
struct spi_master *master;
- struct platform_device *pdev;
+ struct device *dev = p->physport->dev;
- if (butterfly)
+ if (butterfly || !dev)
return;
/* REVISIT: this just _assumes_ a butterfly is there ... no probe,
* and no way to be selective about what it binds to.
*/
- /* FIXME where should master->cdev.dev come from?
- * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
- * setting up a platform device like this is an ugly kluge...
- */
- pdev = platform_device_register_simple("butterfly", -1, NULL, 0);
-
- master = spi_alloc_master(&pdev->dev, sizeof *pp);
+ master = spi_alloc_master(dev, sizeof *pp);
if (!master) {
status = -ENOMEM;
goto done;
parport_frob_control(pp->port, spi_cs_bit, 0);
/* stabilize power with chip in reset (nRESET), and
- * both spi_sck_bit and usi_sck_bit clear (CPOL=0)
+ * spi_sck_bit clear (CPOL=0)
*/
pp->lastbyte |= vcc_bits;
parport_write_data(pp->port, pp->lastbyte);
* (firmware resets at45, acts as spi slave) or neither (we ignore
* both, AVR uses AT45). Here we expect firmware for the first option.
*/
+
pp->info[0].max_speed_hz = 15 * 1000 * 1000;
strcpy(pp->info[0].modalias, "mtd_dataflash");
pp->info[0].platform_data = &flash;
pr_debug("%s: dataflash at %s\n", p->name,
pp->dataflash->dev.bus_id);
-#ifdef HAVE_USI
- /* Bus 2 is only for talking to the AVR, and it can work no
- * matter who masters bus 1; needs appropriate AVR firmware.
- */
- pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
- strcpy(pp->info[1].modalias, "butterfly");
- // pp->info[1].platform_data = ... TBD ... ;
- pp->info[1].chip_select = 2,
- pp->info[1].controller_data = pp;
- pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]);
- if (pp->butterfly)
- pr_debug("%s: butterfly at %s\n", p->name,
- pp->butterfly->dev.bus_id);
-
- /* FIXME setup ACK for the IRQ line ... */
-#endif
-
// dev_info(_what?_, ...)
pr_info("%s: AVR Butterfly\n", p->name);
butterfly = pp;
clean0:
(void) spi_master_put(pp->bitbang.master);
done:
- platform_device_unregister(pdev);
pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
}
static void butterfly_detach(struct parport *p)
{
struct butterfly *pp;
- struct platform_device *pdev;
int status;
/* FIXME this global is ugly ... but, how to quickly get from
butterfly = NULL;
/* stop() unregisters child devices too */
- pdev = to_platform_device(pp->bitbang.master->cdev.dev);
status = spi_bitbang_stop(&pp->bitbang);
/* turn off VCC */
parport_unregister_device(pp->pd);
(void) spi_master_put(pp->bitbang.master);
-
- platform_device_unregister(pdev);
}
static struct parport_driver butterfly_driver = {