2011-05-12 13:42:10 +04:00
/*
* Register map access API - SPI support
*
* Copyright 2011 Wolfson Microelectronics plc
*
* Author : Mark Brown < broonie @ opensource . wolfsonmicro . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/regmap.h>
# include <linux/spi/spi.h>
# include <linux/init.h>
2011-08-16 03:36:06 +04:00
# include <linux/module.h>
2011-05-12 13:42:10 +04:00
2013-01-29 08:14:12 +04:00
# include "internal.h"
struct regmap_async_spi {
struct regmap_async core ;
struct spi_message m ;
struct spi_transfer t [ 2 ] ;
} ;
static void regmap_spi_complete ( void * data )
{
struct regmap_async_spi * async = data ;
regmap_async_complete_cb ( & async - > core , async - > m . status ) ;
}
2012-04-05 01:48:30 +04:00
static int regmap_spi_write ( void * context , const void * data , size_t count )
2011-05-12 13:42:10 +04:00
{
2012-04-05 01:48:30 +04:00
struct device * dev = context ;
2011-05-12 13:42:10 +04:00
struct spi_device * spi = to_spi_device ( dev ) ;
return spi_write ( spi , data , count ) ;
}
2012-04-05 01:48:30 +04:00
static int regmap_spi_gather_write ( void * context ,
2011-05-12 13:42:10 +04:00
const void * reg , size_t reg_len ,
const void * val , size_t val_len )
{
2012-04-05 01:48:30 +04:00
struct device * dev = context ;
2011-05-12 13:42:10 +04:00
struct spi_device * spi = to_spi_device ( dev ) ;
struct spi_message m ;
struct spi_transfer t [ 2 ] = { { . tx_buf = reg , . len = reg_len , } ,
{ . tx_buf = val , . len = val_len , } , } ;
spi_message_init ( & m ) ;
spi_message_add_tail ( & t [ 0 ] , & m ) ;
spi_message_add_tail ( & t [ 1 ] , & m ) ;
return spi_sync ( spi , & m ) ;
}
2013-01-29 08:14:12 +04:00
static int regmap_spi_async_write ( void * context ,
const void * reg , size_t reg_len ,
const void * val , size_t val_len ,
struct regmap_async * a )
{
struct regmap_async_spi * async = container_of ( a ,
struct regmap_async_spi ,
core ) ;
struct device * dev = context ;
struct spi_device * spi = to_spi_device ( dev ) ;
async - > t [ 0 ] . tx_buf = reg ;
async - > t [ 0 ] . len = reg_len ;
async - > t [ 1 ] . tx_buf = val ;
async - > t [ 1 ] . len = val_len ;
spi_message_init ( & async - > m ) ;
spi_message_add_tail ( & async - > t [ 0 ] , & async - > m ) ;
spi_message_add_tail ( & async - > t [ 1 ] , & async - > m ) ;
async - > m . complete = regmap_spi_complete ;
async - > m . context = async ;
return spi_async ( spi , & async - > m ) ;
}
static struct regmap_async * regmap_spi_async_alloc ( void )
{
struct regmap_async_spi * async_spi ;
async_spi = kzalloc ( sizeof ( * async_spi ) , GFP_KERNEL ) ;
2013-02-05 18:14:32 +04:00
if ( ! async_spi )
return NULL ;
2013-01-29 08:14:12 +04:00
return & async_spi - > core ;
}
2012-04-05 01:48:30 +04:00
static int regmap_spi_read ( void * context ,
2011-05-12 13:42:10 +04:00
const void * reg , size_t reg_size ,
void * val , size_t val_size )
{
2012-04-05 01:48:30 +04:00
struct device * dev = context ;
2011-05-12 13:42:10 +04:00
struct spi_device * spi = to_spi_device ( dev ) ;
return spi_write_then_read ( spi , reg , reg_size , val , val_size ) ;
}
static struct regmap_bus regmap_spi = {
. write = regmap_spi_write ,
. gather_write = regmap_spi_gather_write ,
2013-01-29 08:14:12 +04:00
. async_write = regmap_spi_async_write ,
. async_alloc = regmap_spi_async_alloc ,
2011-05-12 13:42:10 +04:00
. read = regmap_spi_read ,
. read_flag_mask = 0x80 ,
} ;
/**
* regmap_init_spi ( ) : Initialise register map
*
* @ spi : Device that will be interacted with
* @ config : Configuration for register map
*
* The return value will be an ERR_PTR ( ) on error or a valid pointer to
* a struct regmap .
*/
struct regmap * regmap_init_spi ( struct spi_device * spi ,
const struct regmap_config * config )
{
2012-04-05 01:48:30 +04:00
return regmap_init ( & spi - > dev , & regmap_spi , & spi - > dev , config ) ;
2011-05-12 13:42:10 +04:00
}
EXPORT_SYMBOL_GPL ( regmap_init_spi ) ;
2011-08-11 21:59:10 +04:00
2012-01-30 23:56:52 +04:00
/**
* devm_regmap_init_spi ( ) : Initialise register map
*
* @ spi : Device that will be interacted with
* @ config : Configuration for register map
*
* The return value will be an ERR_PTR ( ) on error or a valid pointer
* to a struct regmap . The map will be automatically freed by the
* device management code .
*/
struct regmap * devm_regmap_init_spi ( struct spi_device * spi ,
const struct regmap_config * config )
{
2012-04-05 01:48:30 +04:00
return devm_regmap_init ( & spi - > dev , & regmap_spi , & spi - > dev , config ) ;
2012-01-30 23:56:52 +04:00
}
EXPORT_SYMBOL_GPL ( devm_regmap_init_spi ) ;
2011-08-11 21:59:10 +04:00
MODULE_LICENSE ( " GPL " ) ;