From: Peter Henn Date: Wed, 31 Dec 2008 16:06:21 +0000 (+0100) Subject: Test modalias with spi_tty X-Git-Tag: v0.2~5 X-Git-Url: http://git.linex4red.de/pub/spi-gpio-pp.git/commitdiff_plain/ed56ae3ac69596bea18437ef0b0752d64b7e6d49 Test modalias with spi_tty Also add some comments and marks things, which currently unclear. Spi_tty is just a test driver to become more comfortable with the SPI master controller and the parport. --- diff --git a/spi_tty.c b/spi_tty.c index 1a80bea..02e26e1 100644 --- a/spi_tty.c +++ b/spi_tty.c @@ -16,6 +16,16 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * idea: + * separate the butterfly driver into a hotpluggable SPI master controller + * use a board description file, which loads the: + * - the SPI master controller + * - the SPI protocoll driver + * call spi_new_device with + - spi_master = butterfly parport driver (or parameter configurable) + - spi_board_info = infos about Mauro-Lite + */ #include #include @@ -48,6 +58,10 @@ */ /* DATA output bits (pins 2..9 == D0..D7) */ +#define MODALIASLEN 10 +#define DRVNAME "spi_butterfly" +#define DRIVER_VERSION "0.2" + #define butterfly_nreset (1 << 1) /* pin 3 */ #define spi_sck_bit (1 << 0) /* pin 2 */ @@ -61,7 +75,33 @@ /* CONTROL output bits */ #define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ +/* + * Parallel + * Port Direction Signal + * ----------- --------- ------------ + * D0 2 --> SCLK + * D1 3 --> nRESET + * D2 4 --> -- + * D3 5 --> -- + * D4 6 --> -- + * D5 7 --> -- + * D6 8 --> -- + * D7 9 --> MOSI + * GND 25 - GND + * Busy 11 <-- MISO + * Paper 12 <-- -- + * Select 13 <-- -- + * Feed 14 --> -- + * Error 15 <-- -- + * Init 16 --> -- + * Select 17 --> nCS + */ +//***************************************************************************** +// Globals +//***************************************************************************** +/* module parameters */ +static char modalias[MODALIASLEN] = "maurol"; static inline struct butterfly *spidev_to_pp(struct spi_device *spi) { @@ -76,16 +116,17 @@ struct butterfly { struct parport *port; struct pardevice *pd; - u8 lastbyte; + u8 lastbyte; /* hold copy of partport to be faster */ struct spi_message *msg; struct spi_device *butterfly; - struct spi_board_info info[2]; + struct spi_board_info info; }; /*----------------------------------------------------------------------*/ + static inline void setsck(struct spi_device *spi, int is_on) { @@ -99,7 +140,7 @@ setsck(struct spi_device *spi, int is_on) else byte &= ~bit; parport_write_data(pp->port, byte); - pp->lastbyte = byte; + pp->lastbyte = byte; /* use parport mirror to be faster */ } static inline void @@ -115,7 +156,7 @@ setmosi(struct spi_device *spi, int is_on) else byte &= ~bit; parport_write_data(pp->port, byte); - pp->lastbyte = byte; + pp->lastbyte = byte; /* use parport mirror to be faster */ } static inline int getmiso(struct spi_device *spi) @@ -135,6 +176,7 @@ static void butterfly_chipselect(struct spi_device *spi, int value) { struct butterfly *pp = spidev_to_pp(spi); +#if 0 /* set default clock polarity */ if (value != BITBANG_CS_INACTIVE) setsck(spi, spi->mode & SPI_CPOL); @@ -147,6 +189,18 @@ static void butterfly_chipselect(struct spi_device *spi, int value) value = !value; parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); +#else + u8 bit, byte = pp->lastbyte; + + bit = butterfly_nreset; + + if (value) + byte &= ~bit; + else + byte |= bit; + parport_write_data(pp->port, byte); + pp->lastbyte = byte; /* use parport mirror to be faster */ +#endif } @@ -193,26 +247,27 @@ static void butterfly_attach(struct parport *p) } pp = spi_master_get_devdata(master); + master->bus_num = -1; /* dynamic alloc of a bus number */ + master->num_chipselect = 1; + /* * SPI and bitbang hookup - * + * * use default setup(), cleanup(), and transfer() methods; and * only bother implementing mode 0. Start it later. */ - master->bus_num = 42; // hard coded?!? - master->num_chipselect = 2; // hard coded?!? - pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = butterfly_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0; - + pp->bitbang.flags = SPI_3WIRE; // #################################### + /* * parport hookup */ pp->port = p; - pd = parport_register_device(p, "spi_butterfly", + pd = parport_register_device(p, DRVNAME, NULL, NULL, NULL, - 0 /* FLAGS */, pp); + 0 /* FLAGS */, pp); //PARPORT_FLAG_EXCL, pp); if (!pd) { status = -ENOMEM; goto clean0; @@ -223,10 +278,13 @@ static void butterfly_attach(struct parport *p) if (status < 0) goto clean1; + pp->lastbyte = 0; + parport_write_data(pp->port, pp->lastbyte); + /* * Butterfly reset, powerup, run firmware */ - pr_debug("%s: powerup/reset Butterfly\n", p->name); + pr_debug("%s: powerup/reset Butterfly\n", DRVNAME); /* nCS for dataflash (this bit is inverted on output) */ parport_frob_control(pp->port, spi_cs_bit, 0); @@ -238,38 +296,58 @@ static void butterfly_attach(struct parport *p) parport_write_data(pp->port, pp->lastbyte); msleep(5); +#if 0 /* take it out of reset; assume long reset delay */ pp->lastbyte |= butterfly_nreset; parport_write_data(pp->port, pp->lastbyte); - msleep(100); + msleep(10); + /* take reset as trigger signal ############# */ + pp->lastbyte &= ~butterfly_nreset; + parport_write_data(pp->port, pp->lastbyte); +#endif /* * Start SPI ... for now, hide that we're two physical busses. */ status = spi_bitbang_start(&pp->bitbang); - if (status < 0) + if (status < 0) { + pr_warning("%s: spi_bitbang_start failed with status %d\n", + DRVNAME, status); goto clean2; + } - /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR - * (firmware resets at45, acts as spi slave) or neither (we ignore - * both, AVR uses AT45). Here we expect firmware for the first option. + /* + * The modalias name MUST match the device_driver name + * for the bus glue code to match and subsequently bind them. + * We are binding to the generic drivers/hwmon/lm70.c device + * driver. */ - - pp->info[0].max_speed_hz = 15 * 1000 * 1000; - - strcpy(pp->info[0].modalias, "spi_tty"); // name length check ! < KOBJ_NAME_LEN - pp->info[0].platform_data = NULL; // here we should add data structures for subsystem driver ??? - pp->info[0].chip_select = 1; // 0: .. 1: - pp->info[0].controller_data = pp; /* save my structure for later use */ - pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[0]); + if (modalias[0]) { + pr_info("%s: Will load protocol driver: '%s'!\n", DRVNAME, modalias); + } else goto clean2; + + /* need to make this parameter loadable */ + strcpy(pp->info.modalias, modalias); + pp->info.max_speed_hz = 15 * 1000 * 1000; + pp->info.chip_select = 0; // 0: .. 1: + pp->info.mode = SPI_3WIRE | SPI_MODE_0; // ################ + + /* Enable access to our primary data structure via + * the board info's (void *)controller_data. + */ + pp->info.platform_data = NULL; // here we should add data structures for subsystem driver ??? + pp->info.controller_data = pp; /* save my structure for later use */ + pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info); if (pp->butterfly) - pr_debug("%s: dataflash at %s\n", p->name, + pr_info("%s: SPI tty at %s\n", DRVNAME, pp->butterfly->dev.bus_id); - - // dev_info(_what?_, ...) - pr_info("%s: AVR Butterfly\n", p->name); - + else { + pr_warning("%s: spi_new_device failed\n", DRVNAME); + status = -ENODEV; + goto out_bitbang_stop; + } + // pp->butterfly->bits_per_word=16; // ############### /* get spi_bitbang_transfer either via global Symbol, or better * ask it from the driver structure @@ -300,6 +378,8 @@ static void butterfly_attach(struct parport *p) butterfly = pp; return; +out_bitbang_stop: + spi_bitbang_stop(&pp->bitbang); clean2: /* turn off VCC */ parport_write_data(pp->port, 0); @@ -310,7 +390,7 @@ clean1: clean0: (void) spi_master_put(pp->bitbang.master); done: - pr_debug("%s: butterfly probe, fail %d\n", p->name, status); + pr_debug("%s: butterfly probe, fail %d\n", DRVNAME, status); } static void butterfly_detach(struct parport *p) @@ -329,7 +409,6 @@ static void butterfly_detach(struct parport *p) spi_message_free(pp->msg); pr_info("Dealloc SPI message buffer\n"); } - butterfly = NULL; /* stop() unregisters child devices too */ status = spi_bitbang_stop(&pp->bitbang); @@ -342,10 +421,12 @@ static void butterfly_detach(struct parport *p) parport_unregister_device(pp->pd); (void) spi_master_put(pp->bitbang.master); + + butterfly = NULL; } static struct parport_driver butterfly_driver = { - .name = "spi_butterfly", + .name = DRVNAME, .attach = butterfly_attach, .detach = butterfly_detach, }; @@ -365,3 +446,8 @@ module_exit(butterfly_exit); MODULE_DESCRIPTION("Parport Adapter driver for SPI tty Butterfly"); MODULE_LICENSE("GPL"); + +module_param_string(spi_pdrv, modalias, sizeof(modalias), S_IRUGO); +MODULE_PARM_DESC(spi_pdrv, "spi protocol driver name"); + +MODULE_INFO(Version, DRIVER_VERSION);