2019-05-24 13:04:09 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2014-06-06 16:09:17 +04:00
/*
* Load Analog Devices SigmaStudio firmware files
*
* Copyright 2009 - 2011 Analog Devices Inc .
*/
# include <linux/export.h>
2014-11-19 20:29:05 +03:00
# include <linux/i2c.h>
2014-06-06 16:09:17 +04:00
# include <linux/module.h>
2014-11-19 20:29:05 +03:00
# include <linux/slab.h>
# include <asm/unaligned.h>
2014-06-06 16:09:17 +04:00
# include "sigmadsp.h"
2014-11-19 20:29:05 +03:00
static int sigmadsp_write_i2c ( void * control_data ,
unsigned int addr , const uint8_t data [ ] , size_t len )
2014-06-06 16:09:17 +04:00
{
2014-11-19 20:29:05 +03:00
uint8_t * buf ;
int ret ;
buf = kzalloc ( 2 + len , GFP_KERNEL | GFP_DMA ) ;
if ( ! buf )
return - ENOMEM ;
put_unaligned_be16 ( addr , buf ) ;
memcpy ( buf + 2 , data , len ) ;
ret = i2c_master_send ( control_data , buf , len + 2 ) ;
kfree ( buf ) ;
2016-02-10 17:59:28 +03:00
if ( ret < 0 )
return ret ;
return 0 ;
2014-06-06 16:09:17 +04:00
}
2014-11-19 20:29:06 +03:00
static int sigmadsp_read_i2c ( void * control_data ,
unsigned int addr , uint8_t data [ ] , size_t len )
{
struct i2c_client * client = control_data ;
struct i2c_msg msgs [ 2 ] ;
uint8_t buf [ 2 ] ;
int ret ;
put_unaligned_be16 ( addr , buf ) ;
msgs [ 0 ] . addr = client - > addr ;
msgs [ 0 ] . len = sizeof ( buf ) ;
msgs [ 0 ] . buf = buf ;
msgs [ 0 ] . flags = 0 ;
msgs [ 1 ] . addr = client - > addr ;
msgs [ 1 ] . len = len ;
msgs [ 1 ] . buf = data ;
msgs [ 1 ] . flags = I2C_M_RD ;
ret = i2c_transfer ( client - > adapter , msgs , ARRAY_SIZE ( msgs ) ) ;
if ( ret < 0 )
return ret ;
else if ( ret ! = ARRAY_SIZE ( msgs ) )
return - EIO ;
return 0 ;
}
2014-11-19 20:29:05 +03:00
/**
* devm_sigmadsp_init_i2c ( ) - Initialize SigmaDSP instance
* @ client : The parent I2C device
* @ ops : The sigmadsp_ops to use for this instance
* @ firmware_name : Name of the firmware file to load
*
* Allocates a SigmaDSP instance and loads the specified firmware file .
*
* Returns a pointer to a struct sigmadsp on success , or a PTR_ERR ( ) on error .
*/
struct sigmadsp * devm_sigmadsp_init_i2c ( struct i2c_client * client ,
const struct sigmadsp_ops * ops , const char * firmware_name )
2014-06-06 16:09:17 +04:00
{
2014-11-19 20:29:05 +03:00
struct sigmadsp * sigmadsp ;
sigmadsp = devm_sigmadsp_init ( & client - > dev , ops , firmware_name ) ;
if ( IS_ERR ( sigmadsp ) )
return sigmadsp ;
2014-06-06 16:09:17 +04:00
2014-11-19 20:29:05 +03:00
sigmadsp - > control_data = client ;
sigmadsp - > write = sigmadsp_write_i2c ;
2014-11-19 20:29:06 +03:00
sigmadsp - > read = sigmadsp_read_i2c ;
2014-06-06 16:09:17 +04:00
2014-11-19 20:29:05 +03:00
return sigmadsp ;
2014-06-06 16:09:17 +04:00
}
2014-11-19 20:29:05 +03:00
EXPORT_SYMBOL_GPL ( devm_sigmadsp_init_i2c ) ;
2014-06-06 16:09:17 +04:00
MODULE_AUTHOR ( " Lars-Peter Clausen <lars@metafoo.de> " ) ;
MODULE_DESCRIPTION ( " SigmaDSP I2C firmware loader " ) ;
MODULE_LICENSE ( " GPL " ) ;