Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regulator: Convert tps65023 to use regmap API
regmap: Add SPI bus support
regmap: Add I2C bus support
regmap: Add generic non-memory mapped register access API

+778 -70
+7
MAINTAINERS
··· 5327 5327 S: Supported 5328 5328 F: fs/reiserfs/ 5329 5329 5330 + REGISTER MAP ABSTRACTION 5331 + M: Mark Brown <broonie@opensource.wolfsonmicro.com> 5332 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git 5333 + S: Supported 5334 + F: drivers/base/regmap/ 5335 + F: include/linux/regmap.h 5336 + 5330 5337 RFKILL 5331 5338 M: Johannes Berg <johannes@sipsolutions.net> 5332 5339 L: linux-wireless@vger.kernel.org
+2
drivers/base/Kconfig
··· 168 168 bool 169 169 default n 170 170 171 + source "drivers/base/regmap/Kconfig" 172 + 171 173 endmenu
+1
drivers/base/Makefile
··· 17 17 obj-$(CONFIG_MODULES) += module.o 18 18 endif 19 19 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o 20 + obj-$(CONFIG_REGMAP) += regmap/ 20 21 21 22 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG 22 23
+13
drivers/base/regmap/Kconfig
··· 1 + # Generic register map support. There are no user servicable options here, 2 + # this is an API intended to be used by other kernel subsystems. These 3 + # subsystems should select the appropriate symbols. 4 + 5 + config REGMAP 6 + default y if (REGMAP_I2C || REGMAP_SPI) 7 + bool 8 + 9 + config REGMAP_I2C 10 + tristate 11 + 12 + config REGMAP_SPI 13 + tristate
+3
drivers/base/regmap/Makefile
··· 1 + obj-$(CONFIG_REGMAP) += regmap.o 2 + obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o 3 + obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
+115
drivers/base/regmap/regmap-i2c.c
··· 1 + /* 2 + * Register map access API - I2C support 3 + * 4 + * Copyright 2011 Wolfson Microelectronics plc 5 + * 6 + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/regmap.h> 14 + #include <linux/i2c.h> 15 + #include <linux/module.h> 16 + #include <linux/init.h> 17 + 18 + static int regmap_i2c_write(struct device *dev, const void *data, size_t count) 19 + { 20 + struct i2c_client *i2c = to_i2c_client(dev); 21 + int ret; 22 + 23 + ret = i2c_master_send(i2c, data, count); 24 + if (ret == count) 25 + return 0; 26 + else if (ret < 0) 27 + return ret; 28 + else 29 + return -EIO; 30 + } 31 + 32 + static int regmap_i2c_gather_write(struct device *dev, 33 + const void *reg, size_t reg_size, 34 + const void *val, size_t val_size) 35 + { 36 + struct i2c_client *i2c = to_i2c_client(dev); 37 + struct i2c_msg xfer[2]; 38 + int ret; 39 + 40 + /* If the I2C controller can't do a gather tell the core, it 41 + * will substitute in a linear write for us. 42 + */ 43 + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_PROTOCOL_MANGLING)) 44 + return -ENOTSUPP; 45 + 46 + xfer[0].addr = i2c->addr; 47 + xfer[0].flags = 0; 48 + xfer[0].len = reg_size; 49 + xfer[0].buf = (void *)reg; 50 + 51 + xfer[1].addr = i2c->addr; 52 + xfer[1].flags = I2C_M_NOSTART; 53 + xfer[1].len = val_size; 54 + xfer[1].buf = (void *)val; 55 + 56 + ret = i2c_transfer(i2c->adapter, xfer, 2); 57 + if (ret == 2) 58 + return 0; 59 + if (ret < 0) 60 + return ret; 61 + else 62 + return -EIO; 63 + } 64 + 65 + static int regmap_i2c_read(struct device *dev, 66 + const void *reg, size_t reg_size, 67 + void *val, size_t val_size) 68 + { 69 + struct i2c_client *i2c = to_i2c_client(dev); 70 + struct i2c_msg xfer[2]; 71 + int ret; 72 + 73 + xfer[0].addr = i2c->addr; 74 + xfer[0].flags = 0; 75 + xfer[0].len = reg_size; 76 + xfer[0].buf = (void *)reg; 77 + 78 + xfer[1].addr = i2c->addr; 79 + xfer[1].flags = I2C_M_RD; 80 + xfer[1].len = val_size; 81 + xfer[1].buf = val; 82 + 83 + ret = i2c_transfer(i2c->adapter, xfer, 2); 84 + if (ret == 2) 85 + return 0; 86 + else if (ret < 0) 87 + return ret; 88 + else 89 + return -EIO; 90 + } 91 + 92 + static struct regmap_bus regmap_i2c = { 93 + .type = &i2c_bus_type, 94 + .write = regmap_i2c_write, 95 + .gather_write = regmap_i2c_gather_write, 96 + .read = regmap_i2c_read, 97 + .owner = THIS_MODULE, 98 + }; 99 + 100 + /** 101 + * regmap_init_i2c(): Initialise register map 102 + * 103 + * @i2c: Device that will be interacted with 104 + * @config: Configuration for register map 105 + * 106 + * The return value will be an ERR_PTR() on error or a valid pointer to 107 + * a struct regmap. 108 + */ 109 + struct regmap *regmap_init_i2c(struct i2c_client *i2c, 110 + const struct regmap_config *config) 111 + { 112 + return regmap_init(&i2c->dev, &regmap_i2c, config); 113 + } 114 + EXPORT_SYMBOL_GPL(regmap_init_i2c); 115 +
+72
drivers/base/regmap/regmap-spi.c
··· 1 + /* 2 + * Register map access API - SPI support 3 + * 4 + * Copyright 2011 Wolfson Microelectronics plc 5 + * 6 + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/regmap.h> 14 + #include <linux/spi/spi.h> 15 + #include <linux/init.h> 16 + 17 + static int regmap_spi_write(struct device *dev, const void *data, size_t count) 18 + { 19 + struct spi_device *spi = to_spi_device(dev); 20 + 21 + return spi_write(spi, data, count); 22 + } 23 + 24 + static int regmap_spi_gather_write(struct device *dev, 25 + const void *reg, size_t reg_len, 26 + const void *val, size_t val_len) 27 + { 28 + struct spi_device *spi = to_spi_device(dev); 29 + struct spi_message m; 30 + struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, }, 31 + { .tx_buf = val, .len = val_len, }, }; 32 + 33 + spi_message_init(&m); 34 + spi_message_add_tail(&t[0], &m); 35 + spi_message_add_tail(&t[1], &m); 36 + 37 + return spi_sync(spi, &m); 38 + } 39 + 40 + static int regmap_spi_read(struct device *dev, 41 + const void *reg, size_t reg_size, 42 + void *val, size_t val_size) 43 + { 44 + struct spi_device *spi = to_spi_device(dev); 45 + 46 + return spi_write_then_read(spi, reg, reg_size, val, val_size); 47 + } 48 + 49 + static struct regmap_bus regmap_spi = { 50 + .type = &spi_bus_type, 51 + .write = regmap_spi_write, 52 + .gather_write = regmap_spi_gather_write, 53 + .read = regmap_spi_read, 54 + .owner = THIS_MODULE, 55 + .read_flag_mask = 0x80, 56 + }; 57 + 58 + /** 59 + * regmap_init_spi(): Initialise register map 60 + * 61 + * @spi: Device that will be interacted with 62 + * @config: Configuration for register map 63 + * 64 + * The return value will be an ERR_PTR() on error or a valid pointer to 65 + * a struct regmap. 66 + */ 67 + struct regmap *regmap_init_spi(struct spi_device *spi, 68 + const struct regmap_config *config) 69 + { 70 + return regmap_init(&spi->dev, &regmap_spi, config); 71 + } 72 + EXPORT_SYMBOL_GPL(regmap_init_spi);
+455
drivers/base/regmap/regmap.c
··· 1 + /* 2 + * Register map access API 3 + * 4 + * Copyright 2011 Wolfson Microelectronics plc 5 + * 6 + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/slab.h> 14 + #include <linux/module.h> 15 + #include <linux/mutex.h> 16 + #include <linux/err.h> 17 + 18 + #include <linux/regmap.h> 19 + 20 + struct regmap; 21 + 22 + struct regmap_format { 23 + size_t buf_size; 24 + size_t reg_bytes; 25 + size_t val_bytes; 26 + void (*format_write)(struct regmap *map, 27 + unsigned int reg, unsigned int val); 28 + void (*format_reg)(void *buf, unsigned int reg); 29 + void (*format_val)(void *buf, unsigned int val); 30 + unsigned int (*parse_val)(void *buf); 31 + }; 32 + 33 + struct regmap { 34 + struct mutex lock; 35 + 36 + struct device *dev; /* Device we do I/O on */ 37 + void *work_buf; /* Scratch buffer used to format I/O */ 38 + struct regmap_format format; /* Buffer format */ 39 + const struct regmap_bus *bus; 40 + }; 41 + 42 + static void regmap_format_4_12_write(struct regmap *map, 43 + unsigned int reg, unsigned int val) 44 + { 45 + __be16 *out = map->work_buf; 46 + *out = cpu_to_be16((reg << 12) | val); 47 + } 48 + 49 + static void regmap_format_7_9_write(struct regmap *map, 50 + unsigned int reg, unsigned int val) 51 + { 52 + __be16 *out = map->work_buf; 53 + *out = cpu_to_be16((reg << 9) | val); 54 + } 55 + 56 + static void regmap_format_8(void *buf, unsigned int val) 57 + { 58 + u8 *b = buf; 59 + 60 + b[0] = val; 61 + } 62 + 63 + static void regmap_format_16(void *buf, unsigned int val) 64 + { 65 + __be16 *b = buf; 66 + 67 + b[0] = cpu_to_be16(val); 68 + } 69 + 70 + static unsigned int regmap_parse_8(void *buf) 71 + { 72 + u8 *b = buf; 73 + 74 + return b[0]; 75 + } 76 + 77 + static unsigned int regmap_parse_16(void *buf) 78 + { 79 + __be16 *b = buf; 80 + 81 + b[0] = be16_to_cpu(b[0]); 82 + 83 + return b[0]; 84 + } 85 + 86 + /** 87 + * regmap_init(): Initialise register map 88 + * 89 + * @dev: Device that will be interacted with 90 + * @bus: Bus-specific callbacks to use with device 91 + * @config: Configuration for register map 92 + * 93 + * The return value will be an ERR_PTR() on error or a valid pointer to 94 + * a struct regmap. This function should generally not be called 95 + * directly, it should be called by bus-specific init functions. 96 + */ 97 + struct regmap *regmap_init(struct device *dev, 98 + const struct regmap_bus *bus, 99 + const struct regmap_config *config) 100 + { 101 + struct regmap *map; 102 + int ret = -EINVAL; 103 + 104 + if (!bus || !config) 105 + return NULL; 106 + 107 + map = kzalloc(sizeof(*map), GFP_KERNEL); 108 + if (map == NULL) { 109 + ret = -ENOMEM; 110 + goto err; 111 + } 112 + 113 + mutex_init(&map->lock); 114 + map->format.buf_size = (config->reg_bits + config->val_bits) / 8; 115 + map->format.reg_bytes = config->reg_bits / 8; 116 + map->format.val_bytes = config->val_bits / 8; 117 + map->dev = dev; 118 + map->bus = bus; 119 + 120 + switch (config->reg_bits) { 121 + case 4: 122 + switch (config->val_bits) { 123 + case 12: 124 + map->format.format_write = regmap_format_4_12_write; 125 + break; 126 + default: 127 + goto err_map; 128 + } 129 + break; 130 + 131 + case 7: 132 + switch (config->val_bits) { 133 + case 9: 134 + map->format.format_write = regmap_format_7_9_write; 135 + break; 136 + default: 137 + goto err_map; 138 + } 139 + break; 140 + 141 + case 8: 142 + map->format.format_reg = regmap_format_8; 143 + break; 144 + 145 + case 16: 146 + map->format.format_reg = regmap_format_16; 147 + break; 148 + 149 + default: 150 + goto err_map; 151 + } 152 + 153 + switch (config->val_bits) { 154 + case 8: 155 + map->format.format_val = regmap_format_8; 156 + map->format.parse_val = regmap_parse_8; 157 + break; 158 + case 16: 159 + map->format.format_val = regmap_format_16; 160 + map->format.parse_val = regmap_parse_16; 161 + break; 162 + } 163 + 164 + if (!map->format.format_write && 165 + !(map->format.format_reg && map->format.format_val)) 166 + goto err_map; 167 + 168 + map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL); 169 + if (map->work_buf == NULL) { 170 + ret = -ENOMEM; 171 + goto err_bus; 172 + } 173 + 174 + return map; 175 + 176 + err_bus: 177 + module_put(map->bus->owner); 178 + err_map: 179 + kfree(map); 180 + err: 181 + return ERR_PTR(ret); 182 + } 183 + EXPORT_SYMBOL_GPL(regmap_init); 184 + 185 + /** 186 + * regmap_exit(): Free a previously allocated register map 187 + */ 188 + void regmap_exit(struct regmap *map) 189 + { 190 + kfree(map->work_buf); 191 + module_put(map->bus->owner); 192 + kfree(map); 193 + } 194 + EXPORT_SYMBOL_GPL(regmap_exit); 195 + 196 + static int _regmap_raw_write(struct regmap *map, unsigned int reg, 197 + const void *val, size_t val_len) 198 + { 199 + void *buf; 200 + int ret = -ENOTSUPP; 201 + size_t len; 202 + 203 + map->format.format_reg(map->work_buf, reg); 204 + 205 + /* Try to do a gather write if we can */ 206 + if (map->bus->gather_write) 207 + ret = map->bus->gather_write(map->dev, map->work_buf, 208 + map->format.reg_bytes, 209 + val, val_len); 210 + 211 + /* Otherwise fall back on linearising by hand. */ 212 + if (ret == -ENOTSUPP) { 213 + len = map->format.reg_bytes + val_len; 214 + buf = kmalloc(len, GFP_KERNEL); 215 + if (!buf) 216 + return -ENOMEM; 217 + 218 + memcpy(buf, map->work_buf, map->format.reg_bytes); 219 + memcpy(buf + map->format.reg_bytes, val, val_len); 220 + ret = map->bus->write(map->dev, buf, len); 221 + 222 + kfree(buf); 223 + } 224 + 225 + return ret; 226 + } 227 + 228 + static int _regmap_write(struct regmap *map, unsigned int reg, 229 + unsigned int val) 230 + { 231 + BUG_ON(!map->format.format_write && !map->format.format_val); 232 + 233 + if (map->format.format_write) { 234 + map->format.format_write(map, reg, val); 235 + 236 + return map->bus->write(map->dev, map->work_buf, 237 + map->format.buf_size); 238 + } else { 239 + map->format.format_val(map->work_buf + map->format.reg_bytes, 240 + val); 241 + return _regmap_raw_write(map, reg, 242 + map->work_buf + map->format.reg_bytes, 243 + map->format.val_bytes); 244 + } 245 + } 246 + 247 + /** 248 + * regmap_write(): Write a value to a single register 249 + * 250 + * @map: Register map to write to 251 + * @reg: Register to write to 252 + * @val: Value to be written 253 + * 254 + * A value of zero will be returned on success, a negative errno will 255 + * be returned in error cases. 256 + */ 257 + int regmap_write(struct regmap *map, unsigned int reg, unsigned int val) 258 + { 259 + int ret; 260 + 261 + mutex_lock(&map->lock); 262 + 263 + ret = _regmap_write(map, reg, val); 264 + 265 + mutex_unlock(&map->lock); 266 + 267 + return ret; 268 + } 269 + EXPORT_SYMBOL_GPL(regmap_write); 270 + 271 + /** 272 + * regmap_raw_write(): Write raw values to one or more registers 273 + * 274 + * @map: Register map to write to 275 + * @reg: Initial register to write to 276 + * @val: Block of data to be written, laid out for direct transmission to the 277 + * device 278 + * @val_len: Length of data pointed to by val. 279 + * 280 + * This function is intended to be used for things like firmware 281 + * download where a large block of data needs to be transferred to the 282 + * device. No formatting will be done on the data provided. 283 + * 284 + * A value of zero will be returned on success, a negative errno will 285 + * be returned in error cases. 286 + */ 287 + int regmap_raw_write(struct regmap *map, unsigned int reg, 288 + const void *val, size_t val_len) 289 + { 290 + int ret; 291 + 292 + mutex_lock(&map->lock); 293 + 294 + ret = _regmap_raw_write(map, reg, val, val_len); 295 + 296 + mutex_unlock(&map->lock); 297 + 298 + return ret; 299 + } 300 + EXPORT_SYMBOL_GPL(regmap_raw_write); 301 + 302 + static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, 303 + unsigned int val_len) 304 + { 305 + u8 *u8 = map->work_buf; 306 + int ret; 307 + 308 + map->format.format_reg(map->work_buf, reg); 309 + 310 + /* 311 + * Some buses flag reads by setting the high bits in the 312 + * register addresss; since it's always the high bits for all 313 + * current formats we can do this here rather than in 314 + * formatting. This may break if we get interesting formats. 315 + */ 316 + if (map->bus->read_flag_mask) 317 + u8[0] |= map->bus->read_flag_mask; 318 + 319 + ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes, 320 + val, map->format.val_bytes); 321 + if (ret != 0) 322 + return ret; 323 + 324 + return 0; 325 + } 326 + 327 + static int _regmap_read(struct regmap *map, unsigned int reg, 328 + unsigned int *val) 329 + { 330 + int ret; 331 + 332 + if (!map->format.parse_val) 333 + return -EINVAL; 334 + 335 + ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); 336 + if (ret == 0) 337 + *val = map->format.parse_val(map->work_buf); 338 + 339 + return ret; 340 + } 341 + 342 + /** 343 + * regmap_read(): Read a value from a single register 344 + * 345 + * @map: Register map to write to 346 + * @reg: Register to be read from 347 + * @val: Pointer to store read value 348 + * 349 + * A value of zero will be returned on success, a negative errno will 350 + * be returned in error cases. 351 + */ 352 + int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) 353 + { 354 + int ret; 355 + 356 + mutex_lock(&map->lock); 357 + 358 + ret = _regmap_read(map, reg, val); 359 + 360 + mutex_unlock(&map->lock); 361 + 362 + return ret; 363 + } 364 + EXPORT_SYMBOL_GPL(regmap_read); 365 + 366 + /** 367 + * regmap_raw_read(): Read raw data from the device 368 + * 369 + * @map: Register map to write to 370 + * @reg: First register to be read from 371 + * @val: Pointer to store read value 372 + * @val_len: Size of data to read 373 + * 374 + * A value of zero will be returned on success, a negative errno will 375 + * be returned in error cases. 376 + */ 377 + int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, 378 + size_t val_len) 379 + { 380 + int ret; 381 + 382 + mutex_lock(&map->lock); 383 + 384 + ret = _regmap_raw_read(map, reg, val, val_len); 385 + 386 + mutex_unlock(&map->lock); 387 + 388 + return ret; 389 + } 390 + EXPORT_SYMBOL_GPL(regmap_raw_read); 391 + 392 + /** 393 + * regmap_bulk_read(): Read multiple registers from the device 394 + * 395 + * @map: Register map to write to 396 + * @reg: First register to be read from 397 + * @val: Pointer to store read value, in native register size for device 398 + * @val_count: Number of registers to read 399 + * 400 + * A value of zero will be returned on success, a negative errno will 401 + * be returned in error cases. 402 + */ 403 + int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, 404 + size_t val_count) 405 + { 406 + int ret, i; 407 + size_t val_bytes = map->format.val_bytes; 408 + 409 + if (!map->format.parse_val) 410 + return -EINVAL; 411 + 412 + ret = regmap_raw_read(map, reg, val, val_bytes * val_count); 413 + if (ret != 0) 414 + return ret; 415 + 416 + for (i = 0; i < val_count * val_bytes; i += val_bytes) 417 + map->format.parse_val(val + i); 418 + 419 + return 0; 420 + } 421 + EXPORT_SYMBOL_GPL(regmap_bulk_read); 422 + 423 + /** 424 + * remap_update_bits: Perform a read/modify/write cycle on the register map 425 + * 426 + * @map: Register map to update 427 + * @reg: Register to update 428 + * @mask: Bitmask to change 429 + * @val: New value for bitmask 430 + * 431 + * Returns zero for success, a negative number on error. 432 + */ 433 + int regmap_update_bits(struct regmap *map, unsigned int reg, 434 + unsigned int mask, unsigned int val) 435 + { 436 + int ret; 437 + unsigned int tmp; 438 + 439 + mutex_lock(&map->lock); 440 + 441 + ret = _regmap_read(map, reg, &tmp); 442 + if (ret != 0) 443 + goto out; 444 + 445 + tmp &= ~mask; 446 + tmp |= val & mask; 447 + 448 + ret = _regmap_write(map, reg, tmp); 449 + 450 + out: 451 + mutex_unlock(&map->lock); 452 + 453 + return ret; 454 + } 455 + EXPORT_SYMBOL_GPL(regmap_update_bits);
+1
drivers/regulator/Kconfig
··· 235 235 config REGULATOR_TPS65023 236 236 tristate "TI TPS65023 Power regulators" 237 237 depends on I2C 238 + select REGMAP_I2C 238 239 help 239 240 This driver supports TPS65023 voltage regulator chips. TPS65023 provides 240 241 three step-down converters and two general-purpose LDO voltage regulators.
+27 -70
drivers/regulator/tps65023-regulator.c
··· 25 25 #include <linux/i2c.h> 26 26 #include <linux/delay.h> 27 27 #include <linux/slab.h> 28 + #include <linux/regmap.h> 28 29 29 30 /* Register definitions */ 30 31 #define TPS65023_REG_VERSION 0 ··· 126 125 struct i2c_client *client; 127 126 struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; 128 127 const struct tps_info *info[TPS65023_NUM_REGULATOR]; 129 - struct mutex io_lock; 128 + struct regmap *regmap; 130 129 }; 131 - 132 - static inline int tps_65023_read(struct tps_pmic *tps, u8 reg) 133 - { 134 - return i2c_smbus_read_byte_data(tps->client, reg); 135 - } 136 - 137 - static inline int tps_65023_write(struct tps_pmic *tps, u8 reg, u8 val) 138 - { 139 - return i2c_smbus_write_byte_data(tps->client, reg, val); 140 - } 141 130 142 131 static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) 143 132 { 144 - int err, data; 145 - 146 - mutex_lock(&tps->io_lock); 147 - 148 - data = tps_65023_read(tps, reg); 149 - if (data < 0) { 150 - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); 151 - err = data; 152 - goto out; 153 - } 154 - 155 - data |= mask; 156 - err = tps_65023_write(tps, reg, data); 157 - if (err) 158 - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); 159 - 160 - out: 161 - mutex_unlock(&tps->io_lock); 162 - return err; 133 + return regmap_update_bits(tps->regmap, reg, mask, mask); 163 134 } 164 135 165 136 static int tps_65023_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) 166 137 { 167 - int err, data; 168 - 169 - mutex_lock(&tps->io_lock); 170 - 171 - data = tps_65023_read(tps, reg); 172 - if (data < 0) { 173 - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); 174 - err = data; 175 - goto out; 176 - } 177 - 178 - data &= ~mask; 179 - 180 - err = tps_65023_write(tps, reg, data); 181 - if (err) 182 - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); 183 - 184 - out: 185 - mutex_unlock(&tps->io_lock); 186 - return err; 187 - 138 + return regmap_update_bits(tps->regmap, reg, mask, 0); 188 139 } 189 140 190 141 static int tps_65023_reg_read(struct tps_pmic *tps, u8 reg) 191 142 { 192 - int data; 143 + unsigned int val; 144 + int ret; 193 145 194 - mutex_lock(&tps->io_lock); 146 + ret = regmap_read(tps->regmap, reg, &val); 195 147 196 - data = tps_65023_read(tps, reg); 197 - if (data < 0) 198 - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); 199 - 200 - mutex_unlock(&tps->io_lock); 201 - return data; 148 + if (ret != 0) 149 + return ret; 150 + else 151 + return val; 202 152 } 203 153 204 154 static int tps_65023_reg_write(struct tps_pmic *tps, u8 reg, u8 val) 205 155 { 206 - int err; 207 - 208 - mutex_lock(&tps->io_lock); 209 - 210 - err = tps_65023_write(tps, reg, val); 211 - if (err < 0) 212 - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); 213 - 214 - mutex_unlock(&tps->io_lock); 215 - return err; 156 + return regmap_write(tps->regmap, reg, val); 216 157 } 217 158 218 159 static int tps65023_dcdc_is_enabled(struct regulator_dev *dev) ··· 406 463 .list_voltage = tps65023_ldo_list_voltage, 407 464 }; 408 465 466 + static struct regmap_config tps65023_regmap_config = { 467 + .reg_bits = 8, 468 + .val_bits = 8, 469 + }; 470 + 409 471 static int __devinit tps_65023_probe(struct i2c_client *client, 410 472 const struct i2c_device_id *id) 411 473 { ··· 436 488 if (!tps) 437 489 return -ENOMEM; 438 490 439 - mutex_init(&tps->io_lock); 491 + tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config); 492 + if (IS_ERR(tps->regmap)) { 493 + error = PTR_ERR(tps->regmap); 494 + dev_err(&client->dev, "Failed to allocate register map: %d\n", 495 + error); 496 + goto fail_alloc; 497 + } 440 498 441 499 /* common for all regulators */ 442 500 tps->client = client; ··· 481 527 while (--i >= 0) 482 528 regulator_unregister(tps->rdev[i]); 483 529 530 + regmap_exit(tps->regmap); 531 + fail_alloc: 484 532 kfree(tps); 485 533 return error; 486 534 } ··· 501 545 for (i = 0; i < TPS65023_NUM_REGULATOR; i++) 502 546 regulator_unregister(tps->rdev[i]); 503 547 548 + regmap_exit(tps->regmap); 504 549 kfree(tps); 505 550 506 551 return 0;
+82
include/linux/regmap.h
··· 1 + #ifndef __LINUX_REGMAP_H 2 + #define __LINUX_REGMAP_H 3 + 4 + /* 5 + * Register map access API 6 + * 7 + * Copyright 2011 Wolfson Microelectronics plc 8 + * 9 + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License version 2 as 13 + * published by the Free Software Foundation. 14 + */ 15 + 16 + #include <linux/device.h> 17 + #include <linux/list.h> 18 + #include <linux/module.h> 19 + 20 + struct i2c_client; 21 + struct spi_device; 22 + 23 + struct regmap_config { 24 + int reg_bits; 25 + int val_bits; 26 + }; 27 + 28 + typedef int (*regmap_hw_write)(struct device *dev, const void *data, 29 + size_t count); 30 + typedef int (*regmap_hw_gather_write)(struct device *dev, 31 + const void *reg, size_t reg_len, 32 + const void *val, size_t val_len); 33 + typedef int (*regmap_hw_read)(struct device *dev, 34 + const void *reg_buf, size_t reg_size, 35 + void *val_buf, size_t val_size); 36 + 37 + /** 38 + * Description of a hardware bus for the register map infrastructure. 39 + * 40 + * @list: Internal use. 41 + * @type: Bus type, used to identify bus to be used for a device. 42 + * @write: Write operation. 43 + * @gather_write: Write operation with split register/value, return -ENOTSUPP 44 + * if not implemented on a given device. 45 + * @read: Read operation. Data is returned in the buffer used to transmit 46 + * data. 47 + * @owner: Module with the bus implementation, used to pin the implementation 48 + * in memory. 49 + * @read_flag_mask: Mask to be set in the top byte of the register when doing 50 + * a read. 51 + */ 52 + struct regmap_bus { 53 + struct list_head list; 54 + struct bus_type *type; 55 + regmap_hw_write write; 56 + regmap_hw_gather_write gather_write; 57 + regmap_hw_read read; 58 + struct module *owner; 59 + u8 read_flag_mask; 60 + }; 61 + 62 + struct regmap *regmap_init(struct device *dev, 63 + const struct regmap_bus *bus, 64 + const struct regmap_config *config); 65 + struct regmap *regmap_init_i2c(struct i2c_client *i2c, 66 + const struct regmap_config *config); 67 + struct regmap *regmap_init_spi(struct spi_device *dev, 68 + const struct regmap_config *config); 69 + 70 + void regmap_exit(struct regmap *map); 71 + int regmap_write(struct regmap *map, unsigned int reg, unsigned int val); 72 + int regmap_raw_write(struct regmap *map, unsigned int reg, 73 + const void *val, size_t val_len); 74 + int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val); 75 + int regmap_raw_read(struct regmap *map, unsigned int reg, 76 + void *val, size_t val_len); 77 + int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, 78 + size_t val_count); 79 + int regmap_update_bits(struct regmap *map, unsigned int reg, 80 + unsigned int mask, unsigned int val); 81 + 82 + #endif