2008-03-14 11:59:55 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2008 Sascha Hauer, Pengutronix
|
|
|
|
*
|
|
|
|
* Derived from Linux SPI Framework
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005 David Brownell
|
|
|
|
*
|
|
|
|
* 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., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2008-03-11 21:13:06 +00:00
|
|
|
#include <common.h>
|
|
|
|
#include <spi/spi.h>
|
2008-03-14 11:59:55 +00:00
|
|
|
#include <xfuncs.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
/* SPI devices should normally not be created by SPI device drivers; that
|
|
|
|
* would make them board-specific. Similarly with SPI master drivers.
|
|
|
|
* Device registration normally goes into like arch/.../mach.../board-YYY.c
|
|
|
|
* with other readonly (flashable) information about mainboard devices.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct boardinfo {
|
|
|
|
struct list_head list;
|
|
|
|
unsigned n_board_info;
|
|
|
|
struct spi_board_info board_info[0];
|
|
|
|
};
|
|
|
|
|
|
|
|
static LIST_HEAD(board_list);
|
2008-03-11 21:13:06 +00:00
|
|
|
|
2008-03-14 11:59:55 +00:00
|
|
|
/**
|
|
|
|
* spi_new_device - instantiate one new SPI device
|
|
|
|
* @master: Controller to which device is connected
|
|
|
|
* @chip: Describes the SPI device
|
|
|
|
* Context: can sleep
|
|
|
|
*
|
|
|
|
* On typical mainboards, this is purely internal; and it's not needed
|
|
|
|
* after board init creates the hard-wired devices. Some development
|
|
|
|
* platforms may not be able to use spi_register_board_info though, and
|
|
|
|
* this is exported so that for example a USB or parport based adapter
|
|
|
|
* driver could add devices (which it would learn about out-of-band).
|
|
|
|
*
|
|
|
|
* Returns the new device, or NULL.
|
|
|
|
*/
|
|
|
|
struct spi_device *spi_new_device(struct spi_master *master,
|
|
|
|
struct spi_board_info *chip)
|
2008-03-11 21:13:06 +00:00
|
|
|
{
|
2008-03-14 11:59:55 +00:00
|
|
|
struct spi_device *proxy;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
/* Chipselects are numbered 0..max; validate. */
|
|
|
|
if (chip->chip_select >= master->num_chipselect) {
|
|
|
|
debug("cs%d > max %d\n",
|
|
|
|
chip->chip_select,
|
|
|
|
master->num_chipselect);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
proxy = xzalloc(sizeof *proxy);
|
|
|
|
proxy->master = master;
|
|
|
|
proxy->chip_select = chip->chip_select;
|
|
|
|
proxy->max_speed_hz = chip->max_speed_hz;
|
|
|
|
proxy->mode = chip->mode;
|
|
|
|
strcpy(proxy->dev.name, chip->name);
|
|
|
|
strcpy(proxy->dev.id, "pmic");
|
|
|
|
proxy->dev.type_data = proxy;
|
|
|
|
status = register_device(&proxy->dev);
|
|
|
|
|
|
|
|
/* drivers may modify this initial i/o setup */
|
|
|
|
status = master->setup(proxy);
|
|
|
|
if (status < 0) {
|
|
|
|
printf("can't %s %s, status %d\n",
|
|
|
|
"setup", proxy->dev.id, status);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
return proxy;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
free(proxy);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(spi_new_device);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* spi_register_board_info - register SPI devices for a given board
|
|
|
|
* @info: array of chip descriptors
|
|
|
|
* @n: how many descriptors are provided
|
|
|
|
* Context: can sleep
|
|
|
|
*
|
|
|
|
* Board-specific early init code calls this (probably during arch_initcall)
|
|
|
|
* with segments of the SPI device table. Any device nodes are created later,
|
|
|
|
* after the relevant parent SPI controller (bus_num) is defined. We keep
|
|
|
|
* this table of devices forever, so that reloading a controller driver will
|
|
|
|
* not make Linux forget about these hard-wired devices.
|
|
|
|
*
|
|
|
|
* Other code can also call this, e.g. a particular add-on board might provide
|
|
|
|
* SPI devices through its expansion connector, so code initializing that board
|
|
|
|
* would naturally declare its SPI devices.
|
|
|
|
*
|
|
|
|
* The board info passed can safely be __initdata ... but be careful of
|
|
|
|
* any embedded pointers (platform_data, etc), they're copied as-is.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
spi_register_board_info(struct spi_board_info const *info, int n)
|
|
|
|
{
|
|
|
|
struct boardinfo *bi;
|
|
|
|
|
|
|
|
bi = xmalloc(sizeof(*bi) + n * sizeof *info);
|
|
|
|
|
|
|
|
bi->n_board_info = n;
|
|
|
|
memcpy(bi->board_info, info, n * sizeof *info);
|
|
|
|
|
|
|
|
list_add_tail(&bi->list, &board_list);
|
|
|
|
|
2008-03-11 21:13:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-03-14 11:59:55 +00:00
|
|
|
static void scan_boardinfo(struct spi_master *master)
|
|
|
|
{
|
|
|
|
struct boardinfo *bi;
|
|
|
|
|
|
|
|
list_for_each_entry(bi, &board_list, list) {
|
|
|
|
struct spi_board_info *chip = bi->board_info;
|
|
|
|
unsigned n;
|
|
|
|
|
|
|
|
for (n = bi->n_board_info; n > 0; n--, chip++) {
|
|
|
|
debug("%s %d %d\n", __FUNCTION__, chip->bus_num, master->bus_num);
|
|
|
|
if (chip->bus_num != master->bus_num)
|
|
|
|
continue;
|
|
|
|
/* NOTE: this relies on spi_new_device to
|
|
|
|
* issue diagnostics when given bogus inputs
|
|
|
|
*/
|
|
|
|
(void) spi_new_device(master, chip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* spi_register_master - register SPI master controller
|
|
|
|
* @master: initialized master, originally from spi_alloc_master()
|
|
|
|
* Context: can sleep
|
|
|
|
*
|
|
|
|
* SPI master controllers connect to their drivers using some non-SPI bus,
|
|
|
|
* such as the platform bus. The final stage of probe() in that code
|
|
|
|
* includes calling spi_register_master() to hook up to this SPI bus glue.
|
|
|
|
*
|
|
|
|
* SPI controllers use board specific (often SOC specific) bus numbers,
|
|
|
|
* and board-specific addressing for SPI devices combines those numbers
|
|
|
|
* with chip select numbers. Since SPI does not directly support dynamic
|
|
|
|
* device identification, boards need configuration tables telling which
|
|
|
|
* chip is at which address.
|
|
|
|
*
|
|
|
|
* This must be called from context that can sleep. It returns zero on
|
|
|
|
* success, else a negative error code (dropping the master's refcount).
|
|
|
|
* After a successful return, the caller is responsible for calling
|
|
|
|
* spi_unregister_master().
|
|
|
|
*/
|
2008-03-11 21:13:06 +00:00
|
|
|
int spi_register_master(struct spi_master *master)
|
|
|
|
{
|
2008-03-14 11:59:55 +00:00
|
|
|
int status = -ENODEV;
|
|
|
|
|
|
|
|
debug("%s: %s:%s\n", __FUNCTION__, master->dev->name, master->dev->id);
|
|
|
|
|
|
|
|
/* even if it's just one always-selected device, there must
|
|
|
|
* be at least one chipselect
|
|
|
|
*/
|
|
|
|
if (master->num_chipselect == 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
/* populate children from any spi device tables */
|
|
|
|
scan_boardinfo(master);
|
|
|
|
status = 0;
|
|
|
|
|
|
|
|
return status;
|
2008-03-11 21:13:06 +00:00
|
|
|
}
|
2008-03-14 11:59:55 +00:00
|
|
|
EXPORT_SYMBOL(spi_register_master);
|
|
|
|
|
|
|
|
int spi_sync(struct spi_device *spi, struct spi_message *message)
|
|
|
|
{
|
|
|
|
return spi->master->transfer(spi, message);
|
|
|
|
}
|
|
|
|
|