2011-07-20 22:35:37 +01: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
# include <linux/regmap.h>
2011-07-20 22:56:53 +01:00
# include <linux/fs.h>
2012-12-11 01:24:29 +09:00
# include <linux/list.h>
2013-01-27 22:07:38 +08:00
# include <linux/wait.h>
2011-07-20 22:35:37 +01:00
struct regmap ;
2011-09-19 14:34:00 +01:00
struct regcache_ops ;
2011-07-20 22:35:37 +01:00
2012-12-11 01:24:29 +09:00
struct regmap_debugfs_off_cache {
struct list_head list ;
off_t min ;
off_t max ;
unsigned int base_reg ;
2013-02-08 12:47:14 +00:00
unsigned int max_reg ;
2012-12-11 01:24:29 +09:00
} ;
2011-07-20 22:35:37 +01:00
struct regmap_format {
size_t buf_size ;
size_t reg_bytes ;
2012-01-18 10:52:25 +00:00
size_t pad_bytes ;
2011-07-20 22:35:37 +01:00
size_t val_bytes ;
void ( * format_write ) ( struct regmap * map ,
unsigned int reg , unsigned int val ) ;
2012-03-16 12:11:43 +11: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 09:04:51 +08:00
unsigned int ( * parse_val ) ( const void * buf ) ;
void ( * parse_inplace ) ( void * buf ) ;
2011-07-20 22:35:37 +01:00
} ;
2013-01-27 22:07:38 +08:00
struct regmap_async {
struct list_head list ;
struct work_struct cleanup ;
struct regmap * map ;
void * work_buf ;
} ;
2011-07-20 22:35:37 +01:00
struct regmap {
2012-04-04 15:48:28 -06:00
struct mutex mutex ;
spinlock_t spinlock ;
2013-05-24 10:29:22 +02:00
unsigned long spinlock_flags ;
2012-04-04 15:48:28 -06:00
regmap_lock lock ;
regmap_unlock unlock ;
2012-10-16 15:56:59 +02:00
void * lock_arg ; /* This is passed to lock/unlock functions */
2011-07-20 22:35:37 +01: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-04 15:48:30 -06:00
void * bus_context ;
2012-05-08 17:44:40 +01:00
const char * name ;
2011-07-20 22:35:37 +01:00
2013-01-27 22:07:38 +08:00
spinlock_t async_lock ;
wait_queue_head_t async_waitq ;
struct list_head async_list ;
int async_ret ;
2011-07-20 22:56:53 +01:00
# ifdef CONFIG_DEBUG_FS
struct dentry * debugfs ;
2012-04-04 15:48:29 -06:00
const char * debugfs_name ;
2012-12-06 13:29:05 +09:00
unsigned int debugfs_reg_len ;
unsigned int debugfs_val_len ;
unsigned int debugfs_tot_len ;
2012-12-11 01:24:29 +09:00
struct list_head debugfs_off_cache ;
2013-02-20 12:15:23 +00:00
struct mutex cache_lock ;
2011-07-20 22:56:53 +01:00
# endif
2011-07-20 22:35:37 +01: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 15:41:46 +09:00
bool ( * precious_reg ) ( struct device * dev , unsigned int reg ) ;
2012-11-20 15:20:30 +01: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 20:46:32 +02:00
2013-01-12 12:54:12 -08:00
int ( * reg_read ) ( void * context , unsigned int reg , unsigned int * val ) ;
2013-01-12 12:54:13 -08:00
int ( * reg_write ) ( void * context , unsigned int reg , unsigned int val ) ;
2013-01-12 12:54:12 -08:00
2013-01-27 10:49:05 -08:00
bool defer_caching ;
2011-09-05 20:46:32 +02:00
u8 read_flag_mask ;
u8 write_flag_mask ;
2011-09-19 14:34:00 +01:00
2012-03-16 12:11:43 +11:00
/* number of bits to (left) shift the reg value when formatting*/
int reg_shift ;
2012-04-09 13:40:24 -06:00
int reg_stride ;
2012-03-16 12:11:43 +11:00
2011-09-19 14:34:00 +01: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 */
2012-02-06 18:01:35 +00:00
u32 cache_only ;
2011-09-19 14:34:00 +01:00
/* if set, only the HW is modified not the cache */
2012-02-06 18:01:35 +00:00
u32 cache_bypass ;
2011-09-19 14:34:00 +01:00
/* if set, remember to free reg_defaults_raw */
2012-02-06 18:01:35 +00:00
bool cache_free ;
2011-09-19 14:34:00 +01:00
struct reg_default * reg_defaults ;
const void * reg_defaults_raw ;
void * cache ;
2012-02-06 18:01:35 +00:00
u32 cache_dirty ;
2012-01-21 12:01:14 +00:00
2013-03-29 19:18:59 +00:00
unsigned long * cache_present ;
unsigned int cache_present_nbits ;
2012-01-21 12:01:14 +00:00
struct reg_default * patch ;
int patch_regs ;
2012-04-30 23:23:40 +01:00
/* if set, converts bulk rw to single rw */
bool use_single_rw ;
2012-06-15 11:23:56 +01:00
struct rb_root range_tree ;
void * selector_work_buf ; /* Scratch buffer used for selector */
2011-09-19 14:34:00 +01:00
} ;
struct regcache_ops {
const char * name ;
enum regcache_type type ;
int ( * init ) ( struct regmap * map ) ;
int ( * exit ) ( struct regmap * map ) ;
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 19:31:04 +00:00
int ( * sync ) ( struct regmap * map , unsigned int min , unsigned int max ) ;
2013-05-08 13:55:22 +01:00
int ( * drop ) ( struct regmap * map , unsigned int min , unsigned int max ) ;
2011-07-20 22:35:37 +01:00
} ;
2011-08-10 17:14:41 +09: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 10:39:07 +01:00
int _regmap_write ( struct regmap * map , unsigned int reg ,
unsigned int val ) ;
2012-06-15 11:23:56 +01:00
struct regmap_range_node {
struct rb_node node ;
2012-10-03 12:40:47 +01:00
const char * name ;
2012-10-03 13:13:16 +01:00
struct regmap * map ;
2012-06-15 11:23:56 +01: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 13:18:15 +01:00
struct regmap_field {
struct regmap * regmap ;
unsigned int mask ;
/* lsb */
unsigned int shift ;
unsigned int reg ;
} ;
2011-07-20 22:56:53 +01:00
# ifdef CONFIG_DEBUG_FS
extern void regmap_debugfs_initcall ( void ) ;
2012-04-04 15:48:29 -06:00
extern void regmap_debugfs_init ( struct regmap * map , const char * name ) ;
2011-07-20 22:56:53 +01:00
extern void regmap_debugfs_exit ( struct regmap * map ) ;
# else
2011-09-05 22:06:13 +02:00
static inline void regmap_debugfs_initcall ( void ) { }
2012-04-05 23:09:20 -06:00
static inline void regmap_debugfs_init ( struct regmap * map , const char * name ) { }
2011-09-05 22:06:13 +02:00
static inline void regmap_debugfs_exit ( struct regmap * map ) { }
2011-07-20 22:56:53 +01:00
# endif
2011-09-19 14:34:00 +01:00
/* regcache core declarations */
2011-11-16 16:28:16 +01:00
int regcache_init ( struct regmap * map , const struct regmap_config * config ) ;
2011-09-19 14:34:00 +01: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 19:32:28 +00:00
int regcache_sync_block ( struct regmap * map , void * block ,
unsigned int block_base , unsigned int start ,
unsigned int end ) ;
2011-09-19 14:34:00 +01:00
2013-03-13 19:29:36 +00: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 18:03:13 +00: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 14:34:00 +01:00
int regcache_lookup_reg ( struct regmap * map , unsigned int reg ) ;
2013-03-29 19:18:59 +00:00
int regcache_set_reg_present ( struct regmap * map , unsigned int reg ) ;
static inline bool regcache_reg_present ( struct regmap * map , unsigned int reg )
{
if ( ! map - > cache_present )
return true ;
if ( reg > map - > cache_present_nbits )
return false ;
return map - > cache_present [ BIT_WORD ( reg ) ] & BIT_MASK ( reg ) ;
}
2011-09-19 14:34:00 +01:00
2013-03-13 19:19:34 +00:00
int _regmap_raw_write ( struct regmap * map , unsigned int reg ,
const void * val , size_t val_len , bool async ) ;
2013-01-27 22:07:38 +08:00
void regmap_async_complete_cb ( struct regmap_async * async , int ret ) ;
2011-09-19 14:34:02 +01:00
extern struct regcache_ops regcache_rbtree_ops ;
2011-09-19 14:34:03 +01:00
extern struct regcache_ops regcache_lzo_ops ;
2012-12-19 14:51:55 +00:00
extern struct regcache_ops regcache_flat_ops ;
2011-09-19 14:34:03 +01:00
2011-07-20 22:35:37 +01:00
# endif