2019-05-28 09:57:06 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2016-04-05 09:46:19 +02:00
/*
* AD5593R Digital < - > Analog converters driver
*
* Copyright 2015 - 2016 Analog Devices Inc .
* Author : Paul Cercueil < paul . cercueil @ analog . com >
*/
# include "ad5592r-base.h"
# include <linux/bitops.h>
# include <linux/i2c.h>
# include <linux/module.h>
2020-09-10 18:32:15 +01:00
# include <linux/mod_devicetable.h>
2016-04-05 09:46:19 +02:00
2022-09-13 09:34:12 +02:00
# include <asm/unaligned.h>
2016-04-05 09:46:19 +02:00
# define AD5593R_MODE_CONF (0 << 4)
# define AD5593R_MODE_DAC_WRITE (1 << 4)
# define AD5593R_MODE_ADC_READBACK (4 << 4)
# define AD5593R_MODE_DAC_READBACK (5 << 4)
# define AD5593R_MODE_GPIO_READBACK (6 << 4)
# define AD5593R_MODE_REG_READBACK (7 << 4)
2022-09-13 09:34:12 +02:00
static int ad5593r_read_word ( struct i2c_client * i2c , u8 reg , u16 * value )
{
int ret ;
u8 buf [ 2 ] ;
ret = i2c_smbus_write_byte ( i2c , reg ) ;
if ( ret < 0 )
return ret ;
ret = i2c_master_recv ( i2c , buf , sizeof ( buf ) ) ;
if ( ret < 0 )
return ret ;
* value = get_unaligned_be16 ( buf ) ;
return 0 ;
}
2016-04-05 09:46:19 +02:00
static int ad5593r_write_dac ( struct ad5592r_state * st , unsigned chan , u16 value )
{
struct i2c_client * i2c = to_i2c_client ( st - > dev ) ;
return i2c_smbus_write_word_swapped ( i2c ,
AD5593R_MODE_DAC_WRITE | chan , value ) ;
}
static int ad5593r_read_adc ( struct ad5592r_state * st , unsigned chan , u16 * value )
{
struct i2c_client * i2c = to_i2c_client ( st - > dev ) ;
s32 val ;
val = i2c_smbus_write_word_swapped ( i2c ,
AD5593R_MODE_CONF | AD5592R_REG_ADC_SEQ , BIT ( chan ) ) ;
if ( val < 0 )
return ( int ) val ;
2022-09-13 09:34:12 +02:00
return ad5593r_read_word ( i2c , AD5593R_MODE_ADC_READBACK , value ) ;
2016-04-05 09:46:19 +02:00
}
static int ad5593r_reg_write ( struct ad5592r_state * st , u8 reg , u16 value )
{
struct i2c_client * i2c = to_i2c_client ( st - > dev ) ;
return i2c_smbus_write_word_swapped ( i2c ,
AD5593R_MODE_CONF | reg , value ) ;
}
static int ad5593r_reg_read ( struct ad5592r_state * st , u8 reg , u16 * value )
{
struct i2c_client * i2c = to_i2c_client ( st - > dev ) ;
2022-09-13 09:34:12 +02:00
return ad5593r_read_word ( i2c , AD5593R_MODE_REG_READBACK | reg , value ) ;
2016-04-05 09:46:19 +02:00
}
static int ad5593r_gpio_read ( struct ad5592r_state * st , u8 * value )
{
struct i2c_client * i2c = to_i2c_client ( st - > dev ) ;
2022-09-13 09:34:12 +02:00
u16 val ;
int ret ;
2016-04-05 09:46:19 +02:00
2022-09-13 09:34:12 +02:00
ret = ad5593r_read_word ( i2c , AD5593R_MODE_GPIO_READBACK , & val ) ;
if ( ret )
return ret ;
2016-04-05 09:46:19 +02:00
* value = ( u8 ) val ;
return 0 ;
}
static const struct ad5592r_rw_ops ad5593r_rw_ops = {
. write_dac = ad5593r_write_dac ,
. read_adc = ad5593r_read_adc ,
. reg_write = ad5593r_reg_write ,
. reg_read = ad5593r_reg_read ,
. gpio_read = ad5593r_gpio_read ,
} ;
2022-11-18 23:36:59 +01:00
static int ad5593r_i2c_probe ( struct i2c_client * i2c )
2016-04-05 09:46:19 +02:00
{
2022-11-18 23:36:59 +01:00
const struct i2c_device_id * id = i2c_client_get_device_id ( i2c ) ;
2022-09-13 09:34:13 +02:00
if ( ! i2c_check_functionality ( i2c - > adapter ,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C ) )
return - EOPNOTSUPP ;
2016-04-05 09:46:19 +02:00
return ad5592r_probe ( & i2c - > dev , id - > name , & ad5593r_rw_ops ) ;
}
2022-08-15 10:02:30 +02:00
static void ad5593r_i2c_remove ( struct i2c_client * i2c )
2016-04-05 09:46:19 +02:00
{
2021-10-13 22:32:17 +02:00
ad5592r_remove ( & i2c - > dev ) ;
2016-04-05 09:46:19 +02:00
}
static const struct i2c_device_id ad5593r_i2c_ids [ ] = {
{ . name = " ad5593r " , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( i2c , ad5593r_i2c_ids ) ;
static const struct of_device_id ad5593r_of_match [ ] = {
{ . compatible = " adi,ad5593r " , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , ad5593r_of_match ) ;
2016-12-19 13:10:39 +01:00
static const struct acpi_device_id ad5593r_acpi_match [ ] = {
{ " ADS5593 " , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( acpi , ad5593r_acpi_match ) ;
2016-04-05 09:46:19 +02:00
static struct i2c_driver ad5593r_driver = {
. driver = {
. name = " ad5593r " ,
2020-09-10 18:32:15 +01:00
. of_match_table = ad5593r_of_match ,
. acpi_match_table = ad5593r_acpi_match ,
2016-04-05 09:46:19 +02:00
} ,
2023-05-15 22:50:48 +02:00
. probe = ad5593r_i2c_probe ,
2016-04-05 09:46:19 +02:00
. remove = ad5593r_i2c_remove ,
. id_table = ad5593r_i2c_ids ,
} ;
module_i2c_driver ( ad5593r_driver ) ;
MODULE_AUTHOR ( " Paul Cercueil <paul.cercueil@analog.com> " ) ;
2020-04-25 08:56:53 +02:00
MODULE_DESCRIPTION ( " Analog Devices AD5593R multi-channel converters " ) ;
2016-04-05 09:46:19 +02:00
MODULE_LICENSE ( " GPL v2 " ) ;
2022-01-30 20:56:51 +00:00
MODULE_IMPORT_NS ( IIO_AD5592R ) ;