2010-06-25 19:44:10 +04:00
/*
* ADLX345 / 346 Three - Axis Digital Accelerometers ( SPI Interface )
*
* Enter bugs at http : //blackfin.uclinux.org/
*
* Copyright ( C ) 2009 Michael Hennerich , Analog Devices Inc .
* Licensed under the GPL - 2 or later .
*/
# include <linux/input.h> /* BUS_SPI */
# include <linux/module.h>
# include <linux/spi/spi.h>
2011-02-11 20:22:40 +03:00
# include <linux/pm.h>
2010-06-25 19:44:10 +04:00
# include <linux/types.h>
# include "adxl34x.h"
# define MAX_SPI_FREQ_HZ 5000000
# define MAX_FREQ_NO_FIFODELAY 1500000
# define ADXL34X_CMD_MULTB (1 << 6)
# define ADXL34X_CMD_READ (1 << 7)
# define ADXL34X_WRITECMD(reg) (reg & 0x3F)
# define ADXL34X_READCMD(reg) (ADXL34X_CMD_READ | (reg & 0x3F))
# define ADXL34X_READMB_CMD(reg) (ADXL34X_CMD_READ | ADXL34X_CMD_MULTB \
| ( reg & 0x3F ) )
static int adxl34x_spi_read ( struct device * dev , unsigned char reg )
{
struct spi_device * spi = to_spi_device ( dev ) ;
unsigned char cmd ;
cmd = ADXL34X_READCMD ( reg ) ;
return spi_w8r8 ( spi , cmd ) ;
}
static int adxl34x_spi_write ( struct device * dev ,
unsigned char reg , unsigned char val )
{
struct spi_device * spi = to_spi_device ( dev ) ;
unsigned char buf [ 2 ] ;
buf [ 0 ] = ADXL34X_WRITECMD ( reg ) ;
buf [ 1 ] = val ;
return spi_write ( spi , buf , sizeof ( buf ) ) ;
}
static int adxl34x_spi_read_block ( struct device * dev ,
unsigned char reg , int count ,
void * buf )
{
struct spi_device * spi = to_spi_device ( dev ) ;
ssize_t status ;
reg = ADXL34X_READMB_CMD ( reg ) ;
status = spi_write_then_read ( spi , & reg , 1 , buf , count ) ;
return ( status < 0 ) ? status : 0 ;
}
2011-02-11 19:53:04 +03:00
static const struct adxl34x_bus_ops adxl34x_spi_bops = {
2010-06-25 19:44:10 +04:00
. bustype = BUS_SPI ,
. write = adxl34x_spi_write ,
. read = adxl34x_spi_read ,
. read_block = adxl34x_spi_read_block ,
} ;
2012-11-24 09:38:25 +04:00
static int adxl34x_spi_probe ( struct spi_device * spi )
2010-06-25 19:44:10 +04:00
{
struct adxl34x * ac ;
/* don't exceed max specified SPI CLK frequency */
if ( spi - > max_speed_hz > MAX_SPI_FREQ_HZ ) {
dev_err ( & spi - > dev , " SPI CLK %d Hz too fast \n " , spi - > max_speed_hz ) ;
return - EINVAL ;
}
ac = adxl34x_probe ( & spi - > dev , spi - > irq ,
spi - > max_speed_hz > MAX_FREQ_NO_FIFODELAY ,
2011-02-11 19:53:04 +03:00
& adxl34x_spi_bops ) ;
2010-06-25 19:44:10 +04:00
if ( IS_ERR ( ac ) )
return PTR_ERR ( ac ) ;
spi_set_drvdata ( spi , ac ) ;
return 0 ;
}
2012-11-24 09:50:47 +04:00
static int adxl34x_spi_remove ( struct spi_device * spi )
2010-06-25 19:44:10 +04:00
{
2013-04-08 07:52:16 +04:00
struct adxl34x * ac = spi_get_drvdata ( spi ) ;
2010-06-25 19:44:10 +04:00
return adxl34x_remove ( ac ) ;
}
2014-11-02 10:02:46 +03:00
static int __maybe_unused adxl34x_spi_suspend ( struct device * dev )
2010-06-25 19:44:10 +04:00
{
2011-02-11 20:22:40 +03:00
struct spi_device * spi = to_spi_device ( dev ) ;
2013-04-08 07:52:16 +04:00
struct adxl34x * ac = spi_get_drvdata ( spi ) ;
2010-06-25 19:44:10 +04:00
2010-07-01 20:07:33 +04:00
adxl34x_suspend ( ac ) ;
2010-06-25 19:44:10 +04:00
return 0 ;
}
2014-11-02 10:02:46 +03:00
static int __maybe_unused adxl34x_spi_resume ( struct device * dev )
2010-06-25 19:44:10 +04:00
{
2011-02-11 20:22:40 +03:00
struct spi_device * spi = to_spi_device ( dev ) ;
2013-04-08 07:52:16 +04:00
struct adxl34x * ac = spi_get_drvdata ( spi ) ;
2010-06-25 19:44:10 +04:00
2010-07-01 20:07:33 +04:00
adxl34x_resume ( ac ) ;
2010-06-25 19:44:10 +04:00
return 0 ;
}
2011-02-11 20:22:40 +03:00
static SIMPLE_DEV_PM_OPS ( adxl34x_spi_pm , adxl34x_spi_suspend ,
adxl34x_spi_resume ) ;
2010-06-25 19:44:10 +04:00
static struct spi_driver adxl34x_driver = {
. driver = {
. name = " adxl34x " ,
. owner = THIS_MODULE ,
2011-02-11 20:22:40 +03:00
. pm = & adxl34x_spi_pm ,
2010-06-25 19:44:10 +04:00
} ,
. probe = adxl34x_spi_probe ,
2012-11-24 09:27:39 +04:00
. remove = adxl34x_spi_remove ,
2010-06-25 19:44:10 +04:00
} ;
2012-03-17 10:05:26 +04:00
module_spi_driver ( adxl34x_driver ) ;
2010-06-25 19:44:10 +04:00
MODULE_AUTHOR ( " Michael Hennerich <hennerich@blackfin.uclinux.org> " ) ;
MODULE_DESCRIPTION ( " ADXL345/346 Three-Axis Digital Accelerometer SPI Bus Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;