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

mfd: Remove wm8400 custom cache implementation

Save a useful amount of code by removing the custom cache implementation
for wm8400 and using the regmap cache. Also simplify things by not
separately reseting the CODEC registers, this is a sufficiently infrequent
operation that we can simply invalidate the entire cache when this happens.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Mark Brown and committed by
Samuel Ortiz
879eed68 27757e82

+42 -223
+35 -216
drivers/mfd/wm8400-core.c
··· 23 23 #include <linux/regmap.h> 24 24 #include <linux/slab.h> 25 25 26 - static struct { 27 - u16 readable; /* Mask of readable bits */ 28 - u16 writable; /* Mask of writable bits */ 29 - u16 vol; /* Mask of volatile bits */ 30 - int is_codec; /* Register controlled by codec reset */ 31 - u16 default_val; /* Value on reset */ 32 - } reg_data[] = { 33 - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x6172 }, /* R0 */ 34 - { 0x7000, 0x0000, 0x8000, 0, 0x0000 }, /* R1 */ 35 - { 0xFF17, 0xFF17, 0x0000, 0, 0x0000 }, /* R2 */ 36 - { 0xEBF3, 0xEBF3, 0x0000, 1, 0x6000 }, /* R3 */ 37 - { 0x3CF3, 0x3CF3, 0x0000, 1, 0x0000 }, /* R4 */ 38 - { 0xF1F8, 0xF1F8, 0x0000, 1, 0x4050 }, /* R5 */ 39 - { 0xFC1F, 0xFC1F, 0x0000, 1, 0x4000 }, /* R6 */ 40 - { 0xDFDE, 0xDFDE, 0x0000, 1, 0x01C8 }, /* R7 */ 41 - { 0xFCFC, 0xFCFC, 0x0000, 1, 0x0000 }, /* R8 */ 42 - { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R9 */ 43 - { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R10 */ 44 - { 0x27F7, 0x27F7, 0x0000, 1, 0x0004 }, /* R11 */ 45 - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R12 */ 46 - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R13 */ 47 - { 0x1FEF, 0x1FEF, 0x0000, 1, 0x0000 }, /* R14 */ 48 - { 0x0163, 0x0163, 0x0000, 1, 0x0100 }, /* R15 */ 49 - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R16 */ 50 - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R17 */ 51 - { 0x1FFF, 0x0FFF, 0x0000, 1, 0x0000 }, /* R18 */ 52 - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1000 }, /* R19 */ 53 - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R20 */ 54 - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R21 */ 55 - { 0x0FDD, 0x0FDD, 0x0000, 1, 0x8000 }, /* R22 */ 56 - { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0800 }, /* R23 */ 57 - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R24 */ 58 - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R25 */ 59 - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R26 */ 60 - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R27 */ 61 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R28 */ 62 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R29 */ 63 - { 0x0000, 0x0077, 0x0000, 1, 0x0066 }, /* R30 */ 64 - { 0x0000, 0x0033, 0x0000, 1, 0x0022 }, /* R31 */ 65 - { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R32 */ 66 - { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R33 */ 67 - { 0x0000, 0x0003, 0x0000, 1, 0x0003 }, /* R34 */ 68 - { 0x0000, 0x01FF, 0x0000, 1, 0x0003 }, /* R35 */ 69 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R36 */ 70 - { 0x0000, 0x003F, 0x0000, 1, 0x0100 }, /* R37 */ 71 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R38 */ 72 - { 0x0000, 0x000F, 0x0000, 0, 0x0000 }, /* R39 */ 73 - { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R40 */ 74 - { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R41 */ 75 - { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R42 */ 76 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R43 */ 77 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R44 */ 78 - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R45 */ 79 - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R46 */ 80 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R47 */ 81 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R48 */ 82 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R49 */ 83 - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R50 */ 84 - { 0x0000, 0x01B3, 0x0000, 1, 0x0180 }, /* R51 */ 85 - { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R52 */ 86 - { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R53 */ 87 - { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R54 */ 88 - { 0x0000, 0x0001, 0x0000, 1, 0x0000 }, /* R55 */ 89 - { 0x0000, 0x003F, 0x0000, 1, 0x0000 }, /* R56 */ 90 - { 0x0000, 0x004F, 0x0000, 1, 0x0000 }, /* R57 */ 91 - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R58 */ 92 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R59 */ 93 - { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0000 }, /* R60 */ 94 - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x0000 }, /* R61 */ 95 - { 0x03FF, 0x03FF, 0x0000, 1, 0x0000 }, /* R62 */ 96 - { 0x007F, 0x007F, 0x0000, 1, 0x0000 }, /* R63 */ 97 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R64 */ 98 - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R65 */ 99 - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R66 */ 100 - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R67 */ 101 - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R68 */ 102 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R69 */ 103 - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R70 */ 104 - { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R71 */ 105 - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R72 */ 106 - { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R73 */ 107 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R74 */ 108 - { 0x000E, 0x000E, 0x0000, 0, 0x0008 }, /* R75 */ 109 - { 0xE00F, 0xE00F, 0x0000, 0, 0x0000 }, /* R76 */ 110 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R77 */ 111 - { 0x03C0, 0x03C0, 0x0000, 0, 0x02C0 }, /* R78 */ 112 - { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R79 */ 113 - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x0000 }, /* R80 */ 114 - { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R81 */ 115 - { 0x2BFF, 0x0000, 0xffff, 0, 0x0000 }, /* R82 */ 116 - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R83 */ 117 - { 0x80FF, 0x80FF, 0x0000, 0, 0x00ff }, /* R84 */ 118 - }; 119 - 120 - static int wm8400_read(struct wm8400 *wm8400, u8 reg, int num_regs, u16 *dest) 26 + static bool wm8400_volatile(struct device *dev, unsigned int reg) 121 27 { 122 - int i, ret = 0; 123 - 124 - BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); 125 - 126 - /* If there are any volatile reads then read back the entire block */ 127 - for (i = reg; i < reg + num_regs; i++) 128 - if (reg_data[i].vol) { 129 - ret = regmap_bulk_read(wm8400->regmap, reg, dest, 130 - num_regs); 131 - return ret; 132 - } 133 - 134 - /* Otherwise use the cache */ 135 - memcpy(dest, &wm8400->reg_cache[reg], num_regs * sizeof(u16)); 136 - 137 - return 0; 138 - } 139 - 140 - static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs, 141 - u16 *src) 142 - { 143 - int ret, i; 144 - 145 - BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); 146 - 147 - for (i = 0; i < num_regs; i++) { 148 - BUG_ON(!reg_data[reg + i].writable); 149 - wm8400->reg_cache[reg + i] = src[i]; 150 - ret = regmap_write(wm8400->regmap, reg, src[i]); 151 - if (ret != 0) 152 - return ret; 28 + switch (reg) { 29 + case WM8400_INTERRUPT_STATUS_1: 30 + case WM8400_INTERRUPT_LEVELS: 31 + case WM8400_SHUTDOWN_REASON: 32 + return true; 33 + default: 34 + return false; 153 35 } 154 - 155 - return 0; 156 36 } 157 37 158 38 /** ··· 45 165 */ 46 166 u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg) 47 167 { 48 - u16 val; 168 + unsigned int val; 169 + int ret; 49 170 50 - mutex_lock(&wm8400->io_lock); 51 - 52 - wm8400_read(wm8400, reg, 1, &val); 53 - 54 - mutex_unlock(&wm8400->io_lock); 171 + ret = regmap_read(wm8400->regmap, reg, &val); 172 + if (ret < 0) 173 + return ret; 55 174 56 175 return val; 57 176 } ··· 58 179 59 180 int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data) 60 181 { 61 - int ret; 62 - 63 - mutex_lock(&wm8400->io_lock); 64 - 65 - ret = wm8400_read(wm8400, reg, count, data); 66 - 67 - mutex_unlock(&wm8400->io_lock); 68 - 69 - return ret; 182 + return regmap_bulk_read(wm8400->regmap, reg, data, count); 70 183 } 71 - EXPORT_SYMBOL_GPL(wm8400_block_read); 72 - 73 - /** 74 - * wm8400_set_bits - Bitmask write 75 - * 76 - * @wm8400: Pointer to wm8400 control structure 77 - * @reg: Register to access 78 - * @mask: Mask of bits to change 79 - * @val: Value to set for masked bits 80 - */ 81 - int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, u16 mask, u16 val) 82 - { 83 - u16 tmp; 84 - int ret; 85 - 86 - mutex_lock(&wm8400->io_lock); 87 - 88 - ret = wm8400_read(wm8400, reg, 1, &tmp); 89 - tmp = (tmp & ~mask) | val; 90 - if (ret == 0) 91 - ret = wm8400_write(wm8400, reg, 1, &tmp); 92 - 93 - mutex_unlock(&wm8400->io_lock); 94 - 95 - return ret; 96 - } 97 - EXPORT_SYMBOL_GPL(wm8400_set_bits); 98 - 99 - /** 100 - * wm8400_reset_codec_reg_cache - Reset cached codec registers to 101 - * their default values. 102 - */ 103 - void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) 104 - { 105 - int i; 106 - 107 - mutex_lock(&wm8400->io_lock); 108 - 109 - /* Reset all codec registers to their initial value */ 110 - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) 111 - if (reg_data[i].is_codec) 112 - wm8400->reg_cache[i] = reg_data[i].default_val; 113 - 114 - mutex_unlock(&wm8400->io_lock); 115 - } 116 - EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache); 117 184 118 185 static int wm8400_register_codec(struct wm8400 *wm8400) 119 186 { ··· 82 257 static int wm8400_init(struct wm8400 *wm8400, 83 258 struct wm8400_platform_data *pdata) 84 259 { 85 - u16 reg; 86 - int ret, i; 87 - 88 - mutex_init(&wm8400->io_lock); 260 + unsigned int reg; 261 + int ret; 89 262 90 263 dev_set_drvdata(wm8400->dev, wm8400); 91 264 92 265 /* Check that this is actually a WM8400 */ 93 - ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, &i); 266 + ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, &reg); 94 267 if (ret != 0) { 95 268 dev_err(wm8400->dev, "Chip ID register read failed\n"); 96 269 return -EIO; 97 270 } 98 - if (i != reg_data[WM8400_RESET_ID].default_val) { 99 - dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n", i); 271 + if (reg != 0x6172) { 272 + dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n", 273 + reg); 100 274 return -ENODEV; 101 275 } 102 276 103 - /* We don't know what state the hardware is in and since this 104 - * is a PMIC we can't reset it safely so initialise the register 105 - * cache from the hardware. 106 - */ 107 - ret = regmap_raw_read(wm8400->regmap, 0, wm8400->reg_cache, 108 - ARRAY_SIZE(wm8400->reg_cache)); 109 - if (ret != 0) { 110 - dev_err(wm8400->dev, "Register cache read failed\n"); 111 - return -EIO; 112 - } 113 - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) 114 - wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]); 115 - 116 - /* If the codec is in reset use hard coded values */ 117 - if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA)) 118 - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) 119 - if (reg_data[i].is_codec) 120 - wm8400->reg_cache[i] = reg_data[i].default_val; 121 - 122 - ret = wm8400_read(wm8400, WM8400_ID, 1, &reg); 277 + ret = regmap_read(wm8400->regmap, WM8400_ID, &reg); 123 278 if (ret != 0) { 124 279 dev_err(wm8400->dev, "ID register read failed: %d\n", ret); 125 280 return ret; ··· 139 334 .reg_bits = 8, 140 335 .val_bits = 16, 141 336 .max_register = WM8400_REGISTER_COUNT - 1, 337 + 338 + .volatile_reg = wm8400_volatile, 339 + 340 + .cache_type = REGCACHE_RBTREE, 142 341 }; 342 + 343 + /** 344 + * wm8400_reset_codec_reg_cache - Reset cached codec registers to 345 + * their default values. 346 + */ 347 + void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) 348 + { 349 + regmap_reinit_cache(wm8400->regmap, &wm8400_regmap_config); 350 + } 351 + EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache); 143 352 144 353 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 145 354 static int wm8400_i2c_probe(struct i2c_client *i2c,
+7 -7
include/linux/mfd/wm8400-private.h
··· 24 24 #include <linux/mfd/wm8400.h> 25 25 #include <linux/mutex.h> 26 26 #include <linux/platform_device.h> 27 - 28 - struct regmap; 27 + #include <linux/regmap.h> 29 28 30 29 #define WM8400_REGISTER_COUNT 0x55 31 30 32 31 struct wm8400 { 33 32 struct device *dev; 34 - 35 - struct mutex io_lock; 36 33 struct regmap *regmap; 37 - 38 - u16 reg_cache[WM8400_REGISTER_COUNT]; 39 34 40 35 struct platform_device regulators[6]; 41 36 }; ··· 925 930 926 931 u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg); 927 932 int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data); 928 - int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, u16 mask, u16 val); 933 + 934 + static inline int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, 935 + u16 mask, u16 val) 936 + { 937 + return regmap_update_bits(wm8400->regmap, reg, mask, val); 938 + } 929 939 930 940 #endif