2019-05-20 09:19:02 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-01-12 11:41:59 +01:00
/*
* max517 . c - Support for Maxim MAX517 , MAX518 and MAX519
*
* Copyright ( C ) 2010 , 2011 Roland Stigge < stigge @ antcom . de >
*/
# include <linux/module.h>
# include <linux/slab.h>
# include <linux/jiffies.h>
# include <linux/i2c.h>
# include <linux/err.h>
2012-04-25 15:54:58 +01:00
# include <linux/iio/iio.h>
# include <linux/iio/sysfs.h>
2012-06-04 11:36:28 +02:00
# include <linux/iio/dac/max517.h>
2011-01-12 11:41:59 +01:00
# define MAX517_DRV_NAME "max517"
/* Commands */
# define COMMAND_CHANNEL0 0x00
# define COMMAND_CHANNEL1 0x01 /* for MAX518 and MAX519 */
# define COMMAND_PD 0x08 /* Power Down */
enum max517_device_ids {
ID_MAX517 ,
ID_MAX518 ,
ID_MAX519 ,
2015-03-28 09:07:14 +01:00
ID_MAX520 ,
ID_MAX521 ,
2011-01-12 11:41:59 +01:00
} ;
struct max517_data {
2011-01-29 16:36:46 +01:00
struct i2c_client * client ;
2015-03-28 09:07:14 +01:00
unsigned short vref_mv [ 8 ] ;
2011-01-12 11:41:59 +01:00
} ;
/*
* channel : bit 0 : channel 1
* bit 1 : channel 2
* ( this way , it ' s possible to set both channels at once )
*/
2012-06-04 11:36:20 +02:00
static int max517_set_value ( struct iio_dev * indio_dev ,
long val , int channel )
2011-01-12 11:41:59 +01:00
{
2011-10-06 17:14:38 +01:00
struct max517_data * data = iio_priv ( indio_dev ) ;
2011-01-29 16:36:46 +01:00
struct i2c_client * client = data - > client ;
2012-06-04 11:36:20 +02:00
u8 outbuf [ 2 ] ;
2011-01-12 11:41:59 +01:00
int res ;
if ( val < 0 | | val > 255 )
return - EINVAL ;
2012-06-04 11:36:20 +02:00
outbuf [ 0 ] = channel ;
outbuf [ 1 ] = val ;
2011-01-12 11:41:59 +01:00
2012-06-04 11:36:20 +02:00
res = i2c_master_send ( client , outbuf , 2 ) ;
2011-01-12 11:41:59 +01:00
if ( res < 0 )
return res ;
2012-06-04 11:36:20 +02:00
else if ( res ! = 2 )
return - EIO ;
else
return 0 ;
2011-01-12 11:41:59 +01:00
}
2012-06-04 11:36:20 +02:00
static int max517_read_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int * val ,
int * val2 ,
long m )
2011-01-12 11:41:59 +01:00
{
2011-10-06 17:14:38 +01:00
struct max517_data * data = iio_priv ( indio_dev ) ;
2012-06-04 11:36:20 +02:00
switch ( m ) {
case IIO_CHAN_INFO_SCALE :
/* Corresponds to Vref / 2^(bits) */
2013-09-28 10:31:00 +01:00
* val = data - > vref_mv [ chan - > channel ] ;
* val2 = 8 ;
return IIO_VAL_FRACTIONAL_LOG2 ;
2012-06-04 11:36:20 +02:00
default :
break ;
}
return - EINVAL ;
2011-01-12 11:41:59 +01:00
}
2012-06-04 11:36:20 +02:00
static int max517_write_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan , int val , int val2 , long mask )
2011-01-12 11:41:59 +01:00
{
2012-06-04 11:36:20 +02:00
int ret ;
switch ( mask ) {
case IIO_CHAN_INFO_RAW :
ret = max517_set_value ( indio_dev , val , chan - > channel ) ;
break ;
default :
ret = - EINVAL ;
break ;
}
2011-01-12 11:41:59 +01:00
2012-06-04 11:36:20 +02:00
return ret ;
2011-01-12 11:41:59 +01:00
}
2022-06-21 21:26:56 +01:00
static int max517_suspend ( struct device * dev )
2011-01-12 11:41:59 +01:00
{
u8 outbuf = COMMAND_PD ;
2012-02-20 19:37:05 +01:00
return i2c_master_send ( to_i2c_client ( dev ) , & outbuf , 1 ) ;
2011-01-12 11:41:59 +01:00
}
2022-06-21 21:26:56 +01:00
static int max517_resume ( struct device * dev )
2011-01-12 11:41:59 +01:00
{
u8 outbuf = 0 ;
2012-02-20 19:37:05 +01:00
return i2c_master_send ( to_i2c_client ( dev ) , & outbuf , 1 ) ;
2011-01-12 11:41:59 +01:00
}
2022-06-21 21:26:56 +01:00
static DEFINE_SIMPLE_DEV_PM_OPS ( max517_pm_ops , max517_suspend , max517_resume ) ;
2012-02-20 19:37:05 +01:00
2011-05-18 14:42:37 +01:00
static const struct iio_info max517_info = {
2012-06-04 11:36:20 +02:00
. read_raw = max517_read_raw ,
. write_raw = max517_write_raw ,
2011-05-18 14:42:37 +01:00
} ;
2012-06-04 11:36:20 +02:00
# define MAX517_CHANNEL(chan) { \
. type = IIO_VOLTAGE , \
. indexed = 1 , \
. output = 1 , \
. channel = ( chan ) , \
2013-02-27 19:28:22 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) | \
BIT ( IIO_CHAN_INFO_SCALE ) , \
2012-06-04 11:36:20 +02:00
}
static const struct iio_chan_spec max517_channels [ ] = {
MAX517_CHANNEL ( 0 ) ,
2015-03-28 09:07:14 +01:00
MAX517_CHANNEL ( 1 ) ,
MAX517_CHANNEL ( 2 ) ,
MAX517_CHANNEL ( 3 ) ,
MAX517_CHANNEL ( 4 ) ,
MAX517_CHANNEL ( 5 ) ,
MAX517_CHANNEL ( 6 ) ,
MAX517_CHANNEL ( 7 ) ,
2011-05-18 14:42:37 +01:00
} ;
2022-11-18 23:37:03 +01:00
static int max517_probe ( struct i2c_client * client )
2011-01-12 11:41:59 +01:00
{
2022-11-18 23:37:03 +01:00
const struct i2c_device_id * id = i2c_client_get_device_id ( client ) ;
2011-01-12 11:41:59 +01:00
struct max517_data * data ;
2011-06-27 13:07:35 +01:00
struct iio_dev * indio_dev ;
2011-01-12 11:41:59 +01:00
struct max517_platform_data * platform_data = client - > dev . platform_data ;
2015-03-28 09:07:14 +01:00
int chan ;
2011-01-12 11:41:59 +01:00
2013-08-19 12:38:00 +01:00
indio_dev = devm_iio_device_alloc ( & client - > dev , sizeof ( * data ) ) ;
if ( ! indio_dev )
return - ENOMEM ;
2011-06-27 13:07:35 +01:00
data = iio_priv ( indio_dev ) ;
2011-01-29 16:36:46 +01:00
data - > client = client ;
2015-03-28 09:07:14 +01:00
switch ( id - > driver_data ) {
case ID_MAX521 :
indio_dev - > num_channels = 8 ;
break ;
case ID_MAX520 :
indio_dev - > num_channels = 4 ;
break ;
case ID_MAX519 :
case ID_MAX518 :
2012-06-04 11:36:20 +02:00
indio_dev - > num_channels = 2 ;
2015-03-28 09:07:14 +01:00
break ;
default : /* single channel for MAX517 */
indio_dev - > num_channels = 1 ;
break ;
}
2012-06-04 11:36:20 +02:00
indio_dev - > channels = max517_channels ;
2011-06-27 13:07:35 +01:00
indio_dev - > modes = INDIO_DIRECT_MODE ;
2012-06-04 11:36:20 +02:00
indio_dev - > info = & max517_info ;
2011-01-12 11:41:59 +01:00
/*
* Reference voltage on MAX518 and default is 5 V , else take vref_mv
* from platform_data
*/
2015-03-28 09:07:14 +01:00
for ( chan = 0 ; chan < indio_dev - > num_channels ; chan + + ) {
if ( id - > driver_data = = ID_MAX518 | | ! platform_data )
data - > vref_mv [ chan ] = 5000 ; /* mV */
else
data - > vref_mv [ chan ] = platform_data - > vref_mv [ chan ] ;
2011-01-12 11:41:59 +01:00
}
2021-03-14 23:27:09 +05:30
return devm_iio_device_register ( & client - > dev , indio_dev ) ;
2011-01-12 11:41:59 +01:00
}
static const struct i2c_device_id max517_id [ ] = {
{ " max517 " , ID_MAX517 } ,
{ " max518 " , ID_MAX518 } ,
{ " max519 " , ID_MAX519 } ,
2015-03-28 09:07:14 +01:00
{ " max520 " , ID_MAX520 } ,
{ " max521 " , ID_MAX521 } ,
2011-01-12 11:41:59 +01:00
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , max517_id ) ;
static struct i2c_driver max517_driver = {
. driver = {
. name = MAX517_DRV_NAME ,
2022-06-21 21:26:56 +01:00
. pm = pm_sleep_ptr ( & max517_pm_ops ) ,
2011-01-12 11:41:59 +01:00
} ,
2023-05-15 22:50:48 +02:00
. probe = max517_probe ,
2011-01-12 11:41:59 +01:00
. id_table = max517_id ,
} ;
2011-11-16 10:13:38 +01:00
module_i2c_driver ( max517_driver ) ;
2011-01-12 11:41:59 +01:00
MODULE_AUTHOR ( " Roland Stigge <stigge@antcom.de> " ) ;
2015-03-28 09:07:14 +01:00
MODULE_DESCRIPTION ( " MAX517/518/519/520/521 8-bit DAC " ) ;
2011-01-12 11:41:59 +01:00
MODULE_LICENSE ( " GPL " ) ;