2011-07-21 01:35:37 +04:00
/*
* Register map access API internal header
*
* Copyright 2011 Wolfson Microelectronics plc
*
* Author : Mark Brown < broonie @ opensource . wolfsonmicro . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# ifndef _REGMAP_INTERNAL_H
# define _REGMAP_INTERNAL_H
2016-03-29 22:28:33 +03:00
# include <linux/device.h>
2011-07-21 01:35:37 +04:00
# include <linux/regmap.h>
2011-07-21 01:56:53 +04:00
# include <linux/fs.h>
2012-12-10 20:24:29 +04:00
# include <linux/list.h>
2013-01-27 18:07:38 +04:00
# include <linux/wait.h>
2011-07-21 01:35:37 +04:00
struct regmap ;
2011-09-19 17:34:00 +04:00
struct regcache_ops ;
2011-07-21 01:35:37 +04:00
2012-12-10 20:24:29 +04:00
struct regmap_debugfs_off_cache {
struct list_head list ;
off_t min ;
off_t max ;
unsigned int base_reg ;
2013-02-08 16:47:14 +04:00
unsigned int max_reg ;
2012-12-10 20:24:29 +04:00
} ;
2011-07-21 01:35:37 +04:00
struct regmap_format {
size_t buf_size ;
size_t reg_bytes ;
2012-01-18 14:52:25 +04:00
size_t pad_bytes ;
2011-07-21 01:35:37 +04:00
size_t val_bytes ;
void ( * format_write ) ( struct regmap * map ,
unsigned int reg , unsigned int val ) ;
2012-03-16 05:11:43 +04:00
void ( * format_reg ) ( void * buf , unsigned int reg , unsigned int shift ) ;
void ( * format_val ) ( void * buf , unsigned int val , unsigned int shift ) ;
2013-03-04 05:04:51 +04:00
unsigned int ( * parse_val ) ( const void * buf ) ;
void ( * parse_inplace ) ( void * buf ) ;
2011-07-21 01:35:37 +04:00
} ;
2013-01-27 18:07:38 +04:00
struct regmap_async {
struct list_head list ;
struct regmap * map ;
void * work_buf ;
} ;
2011-07-21 01:35:37 +04:00
struct regmap {
2014-09-11 12:19:49 +04:00
union {
struct mutex mutex ;
2014-12-15 11:05:50 +03:00
struct {
spinlock_t spinlock ;
unsigned long spinlock_flags ;
} ;
2014-09-11 12:19:49 +04:00
} ;
2012-04-05 01:48:28 +04:00
regmap_lock lock ;
regmap_unlock unlock ;
2012-10-16 17:56:59 +04:00
void * lock_arg ; /* This is passed to lock/unlock functions */
2015-09-12 02:37:05 +03:00
gfp_t alloc_flags ;
2011-07-21 01:35:37 +04:00
struct device * dev ; /* Device we do I/O on */
void * work_buf ; /* Scratch buffer used to format I/O */
struct regmap_format format ; /* Buffer format */
const struct regmap_bus * bus ;
2012-04-05 01:48:30 +04:00
void * bus_context ;
2012-05-08 20:44:40 +04:00
const char * name ;
2011-07-21 01:35:37 +04:00
2013-10-09 15:28:52 +04:00
bool async ;
2013-01-27 18:07:38 +04:00
spinlock_t async_lock ;
wait_queue_head_t async_waitq ;
struct list_head async_list ;
2013-10-08 02:00:24 +04:00
struct list_head async_free ;
2013-01-27 18:07:38 +04:00
int async_ret ;
2011-07-21 01:56:53 +04:00
# ifdef CONFIG_DEBUG_FS
struct dentry * debugfs ;
2012-04-05 01:48:29 +04:00
const char * debugfs_name ;
2012-12-06 08:29:05 +04:00
unsigned int debugfs_reg_len ;
unsigned int debugfs_val_len ;
unsigned int debugfs_tot_len ;
2012-12-10 20:24:29 +04:00
struct list_head debugfs_off_cache ;
2013-02-20 16:15:23 +04:00
struct mutex cache_lock ;
2011-07-21 01:56:53 +04:00
# endif
2011-07-21 01:35:37 +04:00
unsigned int max_register ;
bool ( * writeable_reg ) ( struct device * dev , unsigned int reg ) ;
bool ( * readable_reg ) ( struct device * dev , unsigned int reg ) ;
bool ( * volatile_reg ) ( struct device * dev , unsigned int reg ) ;
2011-08-08 10:41:46 +04:00
bool ( * precious_reg ) ( struct device * dev , unsigned int reg ) ;
2012-11-20 18:20:30 +04:00
const struct regmap_access_table * wr_table ;
const struct regmap_access_table * rd_table ;
const struct regmap_access_table * volatile_table ;
const struct regmap_access_table * precious_table ;
2011-09-05 22:46:32 +04:00
2013-01-13 00:54:12 +04:00
int ( * reg_read ) ( void * context , unsigned int reg , unsigned int * val ) ;
2013-01-13 00:54:13 +04:00
int ( * reg_write ) ( void * context , unsigned int reg , unsigned int val ) ;
2015-10-01 19:38:07 +03:00
int ( * reg_update_bits ) ( void * context , unsigned int reg ,
unsigned int mask , unsigned int val ) ;
2013-01-13 00:54:12 +04:00
2013-01-27 22:49:05 +04:00
bool defer_caching ;
2016-09-15 23:56:10 +03:00
unsigned long read_flag_mask ;
unsigned long write_flag_mask ;
2011-09-19 17:34:00 +04:00
2012-03-16 05:11:43 +04:00
/* number of bits to (left) shift the reg value when formatting*/
int reg_shift ;
2012-04-09 23:40:24 +04:00
int reg_stride ;
2016-01-04 13:00:33 +03:00
int reg_stride_order ;
2012-03-16 05:11:43 +04:00
2011-09-19 17:34:00 +04:00
/* regcache specific members */
const struct regcache_ops * cache_ops ;
enum regcache_type cache_type ;
/* number of bytes in reg_defaults_raw */
unsigned int cache_size_raw ;
/* number of bytes per word in reg_defaults_raw */
unsigned int cache_word_size ;
/* number of entries in reg_defaults */
unsigned int num_reg_defaults ;
/* number of entries in reg_defaults_raw */
unsigned int num_reg_defaults_raw ;
/* if set, only the cache is modified not the HW */
2015-09-27 01:04:07 +03:00
bool cache_only ;
2011-09-19 17:34:00 +04:00
/* if set, only the HW is modified not the cache */
2015-09-27 01:04:07 +03:00
bool cache_bypass ;
2011-09-19 17:34:00 +04:00
/* if set, remember to free reg_defaults_raw */
2012-02-06 22:01:35 +04:00
bool cache_free ;
2011-09-19 17:34:00 +04:00
struct reg_default * reg_defaults ;
const void * reg_defaults_raw ;
void * cache ;
2015-05-06 01:14:14 +03:00
/* if set, the cache contains newer data than the HW */
2015-09-27 01:04:07 +03:00
bool cache_dirty ;
2015-05-06 01:14:14 +03:00
/* if set, the HW registers are known to match map->reg_defaults */
bool no_sync_defaults ;
2012-01-21 16:01:14 +04:00
2015-07-16 18:36:21 +03:00
struct reg_sequence * patch ;
2012-01-21 16:01:14 +04:00
int patch_regs ;
2012-05-01 02:23:40 +04:00
2015-08-21 11:26:42 +03:00
/* if set, converts bulk read to single read */
bool use_single_read ;
/* if set, converts bulk read to single read */
bool use_single_write ;
2014-03-04 17:54:02 +04:00
/* if set, the device supports multi write mode */
bool can_multi_write ;
2012-06-15 14:23:56 +04:00
2015-08-30 10:33:53 +03:00
/* if set, raw reads/writes are limited to this size */
size_t max_raw_read ;
size_t max_raw_write ;
2012-06-15 14:23:56 +04:00
struct rb_root range_tree ;
void * selector_work_buf ; /* Scratch buffer used for selector */
2011-09-19 17:34:00 +04:00
} ;
struct regcache_ops {
const char * name ;
enum regcache_type type ;
int ( * init ) ( struct regmap * map ) ;
int ( * exit ) ( struct regmap * map ) ;
2014-08-24 17:32:27 +04:00
# ifdef CONFIG_DEBUG_FS
void ( * debugfs_init ) ( struct regmap * map ) ;
# endif
2011-09-19 17:34:00 +04:00
int ( * read ) ( struct regmap * map , unsigned int reg , unsigned int * value ) ;
int ( * write ) ( struct regmap * map , unsigned int reg , unsigned int value ) ;
2012-02-23 23:31:04 +04:00
int ( * sync ) ( struct regmap * map , unsigned int min , unsigned int max ) ;
2013-05-08 16:55:22 +04:00
int ( * drop ) ( struct regmap * map , unsigned int min , unsigned int max ) ;
2011-07-21 01:35:37 +04:00
} ;
2016-08-08 18:44:21 +03:00
bool regmap_cached ( struct regmap * map , unsigned int reg ) ;
2011-08-10 12:14:41 +04:00
bool regmap_writeable ( struct regmap * map , unsigned int reg ) ;
bool regmap_readable ( struct regmap * map , unsigned int reg ) ;
bool regmap_volatile ( struct regmap * map , unsigned int reg ) ;
bool regmap_precious ( struct regmap * map , unsigned int reg ) ;
2011-09-29 13:39:07 +04:00
int _regmap_write ( struct regmap * map , unsigned int reg ,
unsigned int val ) ;
2012-06-15 14:23:56 +04:00
struct regmap_range_node {
struct rb_node node ;
2012-10-03 15:40:47 +04:00
const char * name ;
2012-10-03 16:13:16 +04:00
struct regmap * map ;
2012-06-15 14:23:56 +04:00
unsigned int range_min ;
unsigned int range_max ;
unsigned int selector_reg ;
unsigned int selector_mask ;
int selector_shift ;
unsigned int window_start ;
unsigned int window_len ;
} ;
2013-06-11 16:18:15 +04:00
struct regmap_field {
struct regmap * regmap ;
unsigned int mask ;
/* lsb */
unsigned int shift ;
unsigned int reg ;
2013-09-02 07:30:50 +04:00
unsigned int id_size ;
unsigned int id_offset ;
2013-06-11 16:18:15 +04:00
} ;
2011-07-21 01:56:53 +04:00
# ifdef CONFIG_DEBUG_FS
extern void regmap_debugfs_initcall ( void ) ;
2012-04-05 01:48:29 +04:00
extern void regmap_debugfs_init ( struct regmap * map , const char * name ) ;
2011-07-21 01:56:53 +04:00
extern void regmap_debugfs_exit ( struct regmap * map ) ;
# else
2011-09-06 00:06:13 +04:00
static inline void regmap_debugfs_initcall ( void ) { }
2012-04-06 09:09:20 +04:00
static inline void regmap_debugfs_init ( struct regmap * map , const char * name ) { }
2011-09-06 00:06:13 +04:00
static inline void regmap_debugfs_exit ( struct regmap * map ) { }
2011-07-21 01:56:53 +04:00
# endif
2011-09-19 17:34:00 +04:00
/* regcache core declarations */
2011-11-16 19:28:16 +04:00
int regcache_init ( struct regmap * map , const struct regmap_config * config ) ;
2011-09-19 17:34:00 +04:00
void regcache_exit ( struct regmap * map ) ;
int regcache_read ( struct regmap * map ,
unsigned int reg , unsigned int * value ) ;
int regcache_write ( struct regmap * map ,
unsigned int reg , unsigned int value ) ;
int regcache_sync ( struct regmap * map ) ;
2013-03-29 23:32:28 +04:00
int regcache_sync_block ( struct regmap * map , void * block ,
2013-08-29 12:26:34 +04:00
unsigned long * cache_present ,
2013-03-29 23:32:28 +04:00
unsigned int block_base , unsigned int start ,
unsigned int end ) ;
2011-09-19 17:34:00 +04:00
2013-03-13 23:29:36 +04:00
static inline const void * regcache_get_val_addr ( struct regmap * map ,
const void * base ,
unsigned int idx )
{
return base + ( map - > cache_word_size * idx ) ;
}
2013-02-21 22:03:13 +04:00
unsigned int regcache_get_val ( struct regmap * map , const void * base ,
unsigned int idx ) ;
bool regcache_set_val ( struct regmap * map , void * base , unsigned int idx ,
unsigned int val ) ;
2011-09-19 17:34:00 +04:00
int regcache_lookup_reg ( struct regmap * map , unsigned int reg ) ;
2013-03-13 23:19:34 +04:00
int _regmap_raw_write ( struct regmap * map , unsigned int reg ,
2013-10-09 15:28:52 +04:00
const void * val , size_t val_len ) ;
2013-03-13 23:19:34 +04:00
2013-01-27 18:07:38 +04:00
void regmap_async_complete_cb ( struct regmap_async * async , int ret ) ;
2015-02-03 21:01:18 +03:00
enum regmap_endian regmap_get_val_endian ( struct device * dev ,
const struct regmap_bus * bus ,
const struct regmap_config * config ) ;
2011-09-19 17:34:02 +04:00
extern struct regcache_ops regcache_rbtree_ops ;
2011-09-19 17:34:03 +04:00
extern struct regcache_ops regcache_lzo_ops ;
2012-12-19 18:51:55 +04:00
extern struct regcache_ops regcache_flat_ops ;
2011-09-19 17:34:03 +04:00
2015-03-09 14:20:13 +03:00
static inline const char * regmap_name ( const struct regmap * map )
{
if ( map - > dev )
return dev_name ( map - > dev ) ;
return map - > name ;
}
2016-01-04 13:00:33 +03:00
static inline unsigned int regmap_get_offset ( const struct regmap * map ,
unsigned int index )
{
if ( map - > reg_stride_order > = 0 )
return index < < map - > reg_stride_order ;
else
return index * map - > reg_stride ;
}
2016-01-04 13:00:34 +03:00
static inline unsigned int regcache_get_index_by_order ( const struct regmap * map ,
unsigned int reg )
{
return reg > > map - > reg_stride_order ;
}
2011-07-21 01:35:37 +04:00
# endif