simple SPI controller implementation on PXA2xx SSP port
PATCH 2/2 simple SPI controller implementation on PXA2xx SSP port
This is a preliminary "SPI protocol" driver for the Cirrus Logic CS8415A SPD/IF decoder chip. This driver demostrates some but not all of the features of David Brownell's "simple SPI framework" and is intended to demonstrate and test the PXA SSP driver posted previously.
---- snip ----
drivers/spi/cs8415a.c | 561 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/spi/cirrus.h | 200 +++++++++++++++ include/linux/spi/cs8415a.h | 156 ++++++++++++ 3 files changed, 917 insertions(+)
include/linux/spi/cirrus.h 2005-10-04 13:05:06.897768000 -0700 renamed from include/linux/spi/cirrus.h 1969-12-31 16:00:00.000000000 -0800 +200 -0
@@ -0,0 +1,200 @@ +/* + * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs + * + * 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 + * (at your option) 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. + */ + +#ifndef CIRRUS_H_ +#define CIRRUS_H_ + +#include <linux/list.h> +#include <linux/spi.h> +#include <linux/spinlock.h> +#include <linux/device.h> + +#define READ_CMD 0x21 +#define WRITE_CMD 0x20 +#define TO_MAP(x) ((x & 0x7f) | 0x80) +#define MAX_POOL_NAME_SIZE 64 + +struct cirrus_message_pool { +}; + +struct cirrus_notification { +}; + +struct cirrus_pooled_message { +}; + +inline void _cirrus_setup_async(struct spi_message *message, + void (*chip_callback)(void *context), + void (*user_callback)(int length)) +{ +}; + +inline void *__cirrus_pool_alloc(struct cirrus_message_pool *pool) +{ + return NULL; +} + +inline void __cirrus_pool_free(struct cirrus_message_pool *pool, void* ptr) +{ +} + +inline struct spi_message *_cirrus_alloc_read(struct cirrus_message_pool *pool, + u8 address, + const char* buffer, + size_t length) +{ + return NULL; +} + +inline struct spi_message *_cirrus_alloc_write(struct cirrus_message_pool *pool, + u8 address, + unsigned char* buffer, + unsigned int length) +{ + return NULL; +} + +inline void _cirrus_free(struct cirrus_message_pool *pool, + struct spi_message* message) +{ +} + +inline struct cirrus_message_pool *_cirrus_create_pool(const char* name, + size_t pool_size, + size_t max_message_size) +{ + return NULL; +} + +inline void _cirrus_release_pool(struct cirrus_message_pool *pool) +{ +} + +inline ssize_t _cirrus_read_sync(struct device *dev, u8 address, + const char *buffer, size_t length) +{ + u8 map_buffer[] = { WRITE_CMD, TO_MAP(address) }; + u8 read_cmd_buffer[] = { READ_CMD }; + struct spi_transfer transfers[3]; + struct spi_message message; + + transfers[0].tx_buf = map_buffer; + transfers[0].rx_buf = NULL; + transfers[0].len = ARRAY_SIZE(map_buffer); + transfers[0].cs_change = 0; + transfers[0].delay_usecs = 0; + + transfers[1].tx_buf = read_cmd_buffer; + transfers[1].rx_buf = NULL; + transfers[1].len = ARRAY_SIZE(read_cmd_buffer); + transfers[1].cs_change = 1; + transfers[1].delay_usecs = 0; + + transfers[2].tx_buf = NULL; + transfers[2].rx_buf = (void *)buffer; + transfers[2].len = length; + transfers[2].cs_change = 0; + transfers[2].delay_usecs = 0; + + message.transfers = transfers; + message.n_transfer = ARRAY_SIZE(transfers); + + spi_sync(to_spi_device(dev), &message); + + return message.status < 0 ? message.status : message.actual_length; +} + +inline int _cirrus_write_sync(struct device *dev, u8 address, + const unsigned char *buffer, + unsigned int length) +{ + u8 map_buffer[] = { WRITE_CMD, TO_MAP(address) }; + struct spi_transfer transfers[2]; + struct spi_message message; + + transfers[0].tx_buf = map_buffer, + transfers[0].rx_buf = NULL; + transfers[0].len = ARRAY_SIZE(map_buffer), + transfers[0].cs_change = 1; + transfers[0].delay_usecs = 0; + + transfers[1].tx_buf = (unsigned char *)buffer, + transfers[1].rx_buf = NULL; + transfers[1].len = length, + transfers[1].cs_change = 0; + transfers[1].delay_usecs = 0; + + message.transfers = transfers; + message.n_transfer = ARRAY_SIZE(transfers); + + spi_sync(to_spi_device(dev), &message); + + return message.status < 0 ? message.status : message.actual_length; +} + +inline int _cirrus_read_register_sync(struct device* dev, u8 address) +{ + u8 map_buffer[] = { WRITE_CMD, TO_MAP(address) }; + u8 read_buffer[] = { READ_CMD, 0 }; + struct spi_transfer transfers[2]; + struct spi_message message; + int status; + + transfers[0].tx_buf = map_buffer, + transfers[0].rx_buf = NULL; + transfers[0].len = ARRAY_SIZE(map_buffer), + transfers[0].cs_change = 1; + transfers[0].delay_usecs = 0; + + transfers[1].tx_buf = read_buffer, + transfers[1].rx_buf = read_buffer, + transfers[1].len = ARRAY_SIZE(read_buffer), + transfers[1].cs_change = 0; + transfers[1].delay_usecs = 0; + + message.transfers = transfers; + message.n_transfer = ARRAY_SIZE(transfers); + + status = spi_sync(to_spi_device(dev), &message); + if (status < 0) + return status; + + return message.status < 0 ? message.status : read_buffer[1]; +} + +inline int _cirrus_write_register_sync(struct device* dev, u8 address, u8 data) +{ + u8 write_buffer[] = { WRITE_CMD, TO_MAP(address), data }; + struct spi_transfer transfers[1]; + struct spi_message message; + + transfers[0].tx_buf = write_buffer, + transfers[0].rx_buf = NULL; + transfers[0].len = ARRAY_SIZE(write_buffer), + transfers[0].cs_change = 0; + transfers[0].delay_usecs = 0; + + message.transfers = transfers; + message.n_transfer = ARRAY_SIZE(transfers); + + spi_sync(to_spi_device(dev), &message); + + return message.status; +} + +#endif /*CIRRUS_H_*/
include/linux/spi/cs8415a.h 2005-10-04 14:19:40.422850000 -0700 renamed from include/linux/spi/cs8415a.h 1969-12-31 16:00:00.000000000 -0800 +156 -0
156 lines not on this page · raw message
drivers/spi/cs8415a.c 2005-10-04 14:00:12.279449000 -0700 renamed from drivers/spi/cs8415a.c 1969-12-31 16:00:00.000000000 -0800 +561 -0
561 lines not on this page · raw message