| /* |
| * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation; either version 2 of the |
| * License, or any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * General Public License for more details. |
| * |
| * 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. |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER ); |
| |
| #include <stddef.h> |
| #include <assert.h> |
| #include <unistd.h> |
| #include <gpxe/threewire.h> |
| |
| /** @file |
| * |
| * Three-wire serial devices |
| * |
| */ |
| |
| /** |
| * Read data from three-wire device |
| * |
| * @v nvs NVS device |
| * @v address Address from which to read |
| * @v data Data buffer |
| * @v len Length of data buffer |
| * @ret rc Return status code |
| */ |
| int threewire_read ( struct nvs_device *nvs, unsigned int address, |
| void *data, size_t len ) { |
| struct spi_device *device = nvs_to_spi ( nvs ); |
| struct spi_bus *bus = device->bus; |
| |
| assert ( bus->mode == SPI_MODE_THREEWIRE ); |
| |
| DBG ( "3wire %p reading %zd bytes at %04x\n", device, len, address ); |
| |
| return bus->rw ( bus, device, THREEWIRE_READ, address, |
| NULL, data, len ); |
| } |
| |
| /** |
| * Write data to three-wire device |
| * |
| * @v nvs NVS device |
| * @v address Address from which to read |
| * @v data Data buffer |
| * @v len Length of data buffer |
| * @ret rc Return status code |
| */ |
| int threewire_write ( struct nvs_device *nvs, unsigned int address, |
| const void *data, size_t len ) { |
| struct spi_device *device = nvs_to_spi ( nvs ); |
| struct spi_bus *bus = device->bus; |
| int rc; |
| |
| assert ( bus->mode == SPI_MODE_THREEWIRE ); |
| |
| DBG ( "3wire %p writing %zd bytes at %04x\n", device, len, address ); |
| |
| /* Enable device for writing */ |
| if ( ( rc = bus->rw ( bus, device, THREEWIRE_EWEN, |
| THREEWIRE_EWEN_ADDRESS, NULL, NULL, 0 ) ) != 0 ) |
| return rc; |
| |
| /* Write data */ |
| if ( ( rc = bus->rw ( bus, device, THREEWIRE_WRITE, address, |
| data, NULL, len ) ) != 0 ) |
| return rc; |
| |
| /* Our model of an SPI bus doesn't provide a mechanism for |
| * "assert CS, wait for MISO to become high, so just wait for |
| * long enough to ensure that the write has completed. |
| */ |
| mdelay ( THREEWIRE_WRITE_MDELAY ); |
| |
| return 0; |
| } |