at v6.4 251 lines 7.7 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * nvmem framework provider. 4 * 5 * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 6 * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com> 7 */ 8 9#ifndef _LINUX_NVMEM_PROVIDER_H 10#define _LINUX_NVMEM_PROVIDER_H 11 12#include <linux/device/driver.h> 13#include <linux/err.h> 14#include <linux/errno.h> 15#include <linux/gpio/consumer.h> 16 17struct nvmem_device; 18typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, 19 void *val, size_t bytes); 20typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, 21 void *val, size_t bytes); 22/* used for vendor specific post processing of cell data */ 23typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, 24 unsigned int offset, void *buf, 25 size_t bytes); 26 27enum nvmem_type { 28 NVMEM_TYPE_UNKNOWN = 0, 29 NVMEM_TYPE_EEPROM, 30 NVMEM_TYPE_OTP, 31 NVMEM_TYPE_BATTERY_BACKED, 32 NVMEM_TYPE_FRAM, 33}; 34 35#define NVMEM_DEVID_NONE (-1) 36#define NVMEM_DEVID_AUTO (-2) 37 38/** 39 * struct nvmem_keepout - NVMEM register keepout range. 40 * 41 * @start: The first byte offset to avoid. 42 * @end: One beyond the last byte offset to avoid. 43 * @value: The byte to fill reads with for this region. 44 */ 45struct nvmem_keepout { 46 unsigned int start; 47 unsigned int end; 48 unsigned char value; 49}; 50 51/** 52 * struct nvmem_cell_info - NVMEM cell description 53 * @name: Name. 54 * @offset: Offset within the NVMEM device. 55 * @raw_len: Length of raw data (without post processing). 56 * @bytes: Length of the cell. 57 * @bit_offset: Bit offset if cell is smaller than a byte. 58 * @nbits: Number of bits. 59 * @np: Optional device_node pointer. 60 * @read_post_process: Callback for optional post processing of cell data 61 * on reads. 62 * @priv: Opaque data passed to the read_post_process hook. 63 */ 64struct nvmem_cell_info { 65 const char *name; 66 unsigned int offset; 67 size_t raw_len; 68 unsigned int bytes; 69 unsigned int bit_offset; 70 unsigned int nbits; 71 struct device_node *np; 72 nvmem_cell_post_process_t read_post_process; 73 void *priv; 74}; 75 76/** 77 * struct nvmem_config - NVMEM device configuration 78 * 79 * @dev: Parent device. 80 * @name: Optional name. 81 * @id: Optional device ID used in full name. Ignored if name is NULL. 82 * @owner: Pointer to exporter module. Used for refcounting. 83 * @cells: Optional array of pre-defined NVMEM cells. 84 * @ncells: Number of elements in cells. 85 * @keepout: Optional array of keepout ranges (sorted ascending by start). 86 * @nkeepout: Number of elements in the keepout array. 87 * @type: Type of the nvmem storage 88 * @read_only: Device is read-only. 89 * @root_only: Device is accessibly to root only. 90 * @of_node: If given, this will be used instead of the parent's of_node. 91 * @no_of_node: Device should not use the parent's of_node even if it's !NULL. 92 * @reg_read: Callback to read data. 93 * @reg_write: Callback to write data. 94 * @size: Device size. 95 * @word_size: Minimum read/write access granularity. 96 * @stride: Minimum read/write access stride. 97 * @priv: User context passed to read/write callbacks. 98 * @ignore_wp: Write Protect pin is managed by the provider. 99 * @layout: Fixed layout associated with this nvmem device. 100 * 101 * Note: A default "nvmem<id>" name will be assigned to the device if 102 * no name is specified in its configuration. In such case "<id>" is 103 * generated with ida_simple_get() and provided id field is ignored. 104 * 105 * Note: Specifying name and setting id to -1 implies a unique device 106 * whose name is provided as-is (kept unaltered). 107 */ 108struct nvmem_config { 109 struct device *dev; 110 const char *name; 111 int id; 112 struct module *owner; 113 const struct nvmem_cell_info *cells; 114 int ncells; 115 const struct nvmem_keepout *keepout; 116 unsigned int nkeepout; 117 enum nvmem_type type; 118 bool read_only; 119 bool root_only; 120 bool ignore_wp; 121 struct nvmem_layout *layout; 122 struct device_node *of_node; 123 bool no_of_node; 124 nvmem_reg_read_t reg_read; 125 nvmem_reg_write_t reg_write; 126 int size; 127 int word_size; 128 int stride; 129 void *priv; 130 /* To be only used by old driver/misc/eeprom drivers */ 131 bool compat; 132 struct device *base_dev; 133}; 134 135/** 136 * struct nvmem_cell_table - NVMEM cell definitions for given provider 137 * 138 * @nvmem_name: Provider name. 139 * @cells: Array of cell definitions. 140 * @ncells: Number of cell definitions in the array. 141 * @node: List node. 142 * 143 * This structure together with related helper functions is provided for users 144 * that don't can't access the nvmem provided structure but wish to register 145 * cell definitions for it e.g. board files registering an EEPROM device. 146 */ 147struct nvmem_cell_table { 148 const char *nvmem_name; 149 const struct nvmem_cell_info *cells; 150 size_t ncells; 151 struct list_head node; 152}; 153 154/** 155 * struct nvmem_layout - NVMEM layout definitions 156 * 157 * @name: Layout name. 158 * @of_match_table: Open firmware match table. 159 * @add_cells: Will be called if a nvmem device is found which 160 * has this layout. The function will add layout 161 * specific cells with nvmem_add_one_cell(). 162 * @fixup_cell_info: Will be called before a cell is added. Can be 163 * used to modify the nvmem_cell_info. 164 * @owner: Pointer to struct module. 165 * @node: List node. 166 * 167 * A nvmem device can hold a well defined structure which can just be 168 * evaluated during runtime. For example a TLV list, or a list of "name=val" 169 * pairs. A nvmem layout can parse the nvmem device and add appropriate 170 * cells. 171 */ 172struct nvmem_layout { 173 const char *name; 174 const struct of_device_id *of_match_table; 175 int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, 176 struct nvmem_layout *layout); 177 void (*fixup_cell_info)(struct nvmem_device *nvmem, 178 struct nvmem_layout *layout, 179 struct nvmem_cell_info *cell); 180 181 /* private */ 182 struct module *owner; 183 struct list_head node; 184}; 185 186#if IS_ENABLED(CONFIG_NVMEM) 187 188struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); 189void nvmem_unregister(struct nvmem_device *nvmem); 190 191struct nvmem_device *devm_nvmem_register(struct device *dev, 192 const struct nvmem_config *cfg); 193 194void nvmem_add_cell_table(struct nvmem_cell_table *table); 195void nvmem_del_cell_table(struct nvmem_cell_table *table); 196 197int nvmem_add_one_cell(struct nvmem_device *nvmem, 198 const struct nvmem_cell_info *info); 199 200int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); 201#define nvmem_layout_register(layout) \ 202 __nvmem_layout_register(layout, THIS_MODULE) 203void nvmem_layout_unregister(struct nvmem_layout *layout); 204 205const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, 206 struct nvmem_layout *layout); 207 208#else 209 210static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) 211{ 212 return ERR_PTR(-EOPNOTSUPP); 213} 214 215static inline void nvmem_unregister(struct nvmem_device *nvmem) {} 216 217static inline struct nvmem_device * 218devm_nvmem_register(struct device *dev, const struct nvmem_config *c) 219{ 220 return nvmem_register(c); 221} 222 223static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} 224static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} 225static inline int nvmem_add_one_cell(struct nvmem_device *nvmem, 226 const struct nvmem_cell_info *info) 227{ 228 return -EOPNOTSUPP; 229} 230 231static inline int nvmem_layout_register(struct nvmem_layout *layout) 232{ 233 return -EOPNOTSUPP; 234} 235 236static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} 237 238static inline const void * 239nvmem_layout_get_match_data(struct nvmem_device *nvmem, 240 struct nvmem_layout *layout) 241{ 242 return NULL; 243} 244 245#endif /* CONFIG_NVMEM */ 246 247#define module_nvmem_layout_driver(__layout_driver) \ 248 module_driver(__layout_driver, nvmem_layout_register, \ 249 nvmem_layout_unregister) 250 251#endif /* ifndef _LINUX_NVMEM_PROVIDER_H */