2011-06-09 23:50:00 +04:00
/*
* tps65912 - spi . c - - SPI access for TI TPS65912x PMIC
*
* Copyright 2011 Texas Instruments Inc .
*
* Author : Margarita Olaya Cabrera < magi @ slimlogic . 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 ( at your
* option ) any later version .
*
* This driver is based on wm8350 implementation .
*/
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/gpio.h>
# include <linux/spi/spi.h>
# include <linux/mfd/core.h>
# include <linux/mfd/tps65912.h>
static int tps65912_spi_write ( struct tps65912 * tps65912 , u8 addr ,
int bytes , void * src )
{
struct spi_device * spi = tps65912 - > control_data ;
u8 * data = ( u8 * ) src ;
int ret ;
/* bit 23 is the read/write bit */
unsigned long spi_data = 1 < < 23 | addr < < 15 | * data ;
struct spi_transfer xfer ;
struct spi_message msg ;
2014-07-18 16:00:17 +04:00
u32 tx_buf ;
2011-06-09 23:50:00 +04:00
tx_buf = spi_data ;
xfer . tx_buf = & tx_buf ;
xfer . rx_buf = NULL ;
xfer . len = sizeof ( unsigned long ) ;
xfer . bits_per_word = 24 ;
spi_message_init ( & msg ) ;
spi_message_add_tail ( & xfer , & msg ) ;
ret = spi_sync ( spi , & msg ) ;
return ret ;
}
static int tps65912_spi_read ( struct tps65912 * tps65912 , u8 addr ,
int bytes , void * dest )
{
struct spi_device * spi = tps65912 - > control_data ;
/* bit 23 is the read/write bit */
unsigned long spi_data = 0 < < 23 | addr < < 15 ;
struct spi_transfer xfer ;
struct spi_message msg ;
int ret ;
u8 * data = ( u8 * ) dest ;
u32 tx_buf , rx_buf ;
tx_buf = spi_data ;
rx_buf = 0 ;
xfer . tx_buf = & tx_buf ;
xfer . rx_buf = & rx_buf ;
xfer . len = sizeof ( unsigned long ) ;
xfer . bits_per_word = 24 ;
spi_message_init ( & msg ) ;
spi_message_add_tail ( & xfer , & msg ) ;
if ( spi = = NULL )
return 0 ;
ret = spi_sync ( spi , & msg ) ;
if ( ret = = 0 )
* data = ( u8 ) ( rx_buf & 0xFF ) ;
return ret ;
}
2012-11-19 22:23:04 +04:00
static int tps65912_spi_probe ( struct spi_device * spi )
2011-06-09 23:50:00 +04:00
{
struct tps65912 * tps65912 ;
2013-05-23 19:25:02 +04:00
tps65912 = devm_kzalloc ( & spi - > dev ,
sizeof ( struct tps65912 ) , GFP_KERNEL ) ;
2011-06-09 23:50:00 +04:00
if ( tps65912 = = NULL )
return - ENOMEM ;
tps65912 - > dev = & spi - > dev ;
tps65912 - > control_data = spi ;
tps65912 - > read = tps65912_spi_read ;
tps65912 - > write = tps65912_spi_write ;
spi_set_drvdata ( spi , tps65912 ) ;
return tps65912_device_init ( tps65912 ) ;
}
2012-11-19 22:26:01 +04:00
static int tps65912_spi_remove ( struct spi_device * spi )
2011-06-09 23:50:00 +04:00
{
struct tps65912 * tps65912 = spi_get_drvdata ( spi ) ;
tps65912_device_exit ( tps65912 ) ;
return 0 ;
}
static struct spi_driver tps65912_spi_driver = {
. driver = {
. name = " tps65912 " ,
. owner = THIS_MODULE ,
} ,
. probe = tps65912_spi_probe ,
2012-11-19 22:20:24 +04:00
. remove = tps65912_spi_remove ,
2011-06-09 23:50:00 +04:00
} ;
static int __init tps65912_spi_init ( void )
{
int ret ;
ret = spi_register_driver ( & tps65912_spi_driver ) ;
if ( ret ! = 0 )
pr_err ( " Failed to register TPS65912 SPI driver: %d \n " , ret ) ;
return 0 ;
}
/* init early so consumer devices can complete system boot */
subsys_initcall ( tps65912_spi_init ) ;
static void __exit tps65912_spi_exit ( void )
{
spi_unregister_driver ( & tps65912_spi_driver ) ;
}
module_exit ( tps65912_spi_exit ) ;
MODULE_AUTHOR ( " Margarita Olaya <magi@slimlogic.co.uk> " ) ;
MODULE_DESCRIPTION ( " SPI support for TPS65912 chip family mfd " ) ;
MODULE_LICENSE ( " GPL " ) ;