Commit 09fd19da0074b86030a00303522b2ba63a4399b7

Authored by Lee Jones

Merge tag 'ib-asoc-3.14.2' into for-mfd-next

Immutable branch between MFD and ASoC due for the v3.14 merge window

Showing 3 changed files Side-by-side Diff

drivers/mfd/twl-core.c
... ... @@ -47,6 +47,9 @@
47 47 #include <linux/i2c.h>
48 48 #include <linux/i2c/twl.h>
49 49  
  50 +/* Register descriptions for audio */
  51 +#include <linux/mfd/twl4030-audio.h>
  52 +
50 53 #include "twl-core.h"
51 54  
52 55 /*
... ... @@ -200,6 +203,105 @@
200 203 { 2, TWL5031_BASEADD_INTERRUPTS },
201 204 };
202 205  
  206 +static struct reg_default twl4030_49_defaults[] = {
  207 + /* Audio Registers */
  208 + { 0x01, 0x00}, /* CODEC_MODE */
  209 + { 0x02, 0x00}, /* OPTION */
  210 + /* 0x03 Unused */
  211 + { 0x04, 0x00}, /* MICBIAS_CTL */
  212 + { 0x05, 0x00}, /* ANAMICL */
  213 + { 0x06, 0x00}, /* ANAMICR */
  214 + { 0x07, 0x00}, /* AVADC_CTL */
  215 + { 0x08, 0x00}, /* ADCMICSEL */
  216 + { 0x09, 0x00}, /* DIGMIXING */
  217 + { 0x0a, 0x0f}, /* ATXL1PGA */
  218 + { 0x0b, 0x0f}, /* ATXR1PGA */
  219 + { 0x0c, 0x0f}, /* AVTXL2PGA */
  220 + { 0x0d, 0x0f}, /* AVTXR2PGA */
  221 + { 0x0e, 0x00}, /* AUDIO_IF */
  222 + { 0x0f, 0x00}, /* VOICE_IF */
  223 + { 0x10, 0x3f}, /* ARXR1PGA */
  224 + { 0x11, 0x3f}, /* ARXL1PGA */
  225 + { 0x12, 0x3f}, /* ARXR2PGA */
  226 + { 0x13, 0x3f}, /* ARXL2PGA */
  227 + { 0x14, 0x25}, /* VRXPGA */
  228 + { 0x15, 0x00}, /* VSTPGA */
  229 + { 0x16, 0x00}, /* VRX2ARXPGA */
  230 + { 0x17, 0x00}, /* AVDAC_CTL */
  231 + { 0x18, 0x00}, /* ARX2VTXPGA */
  232 + { 0x19, 0x32}, /* ARXL1_APGA_CTL*/
  233 + { 0x1a, 0x32}, /* ARXR1_APGA_CTL*/
  234 + { 0x1b, 0x32}, /* ARXL2_APGA_CTL*/
  235 + { 0x1c, 0x32}, /* ARXR2_APGA_CTL*/
  236 + { 0x1d, 0x00}, /* ATX2ARXPGA */
  237 + { 0x1e, 0x00}, /* BT_IF */
  238 + { 0x1f, 0x55}, /* BTPGA */
  239 + { 0x20, 0x00}, /* BTSTPGA */
  240 + { 0x21, 0x00}, /* EAR_CTL */
  241 + { 0x22, 0x00}, /* HS_SEL */
  242 + { 0x23, 0x00}, /* HS_GAIN_SET */
  243 + { 0x24, 0x00}, /* HS_POPN_SET */
  244 + { 0x25, 0x00}, /* PREDL_CTL */
  245 + { 0x26, 0x00}, /* PREDR_CTL */
  246 + { 0x27, 0x00}, /* PRECKL_CTL */
  247 + { 0x28, 0x00}, /* PRECKR_CTL */
  248 + { 0x29, 0x00}, /* HFL_CTL */
  249 + { 0x2a, 0x00}, /* HFR_CTL */
  250 + { 0x2b, 0x05}, /* ALC_CTL */
  251 + { 0x2c, 0x00}, /* ALC_SET1 */
  252 + { 0x2d, 0x00}, /* ALC_SET2 */
  253 + { 0x2e, 0x00}, /* BOOST_CTL */
  254 + { 0x2f, 0x00}, /* SOFTVOL_CTL */
  255 + { 0x30, 0x13}, /* DTMF_FREQSEL */
  256 + { 0x31, 0x00}, /* DTMF_TONEXT1H */
  257 + { 0x32, 0x00}, /* DTMF_TONEXT1L */
  258 + { 0x33, 0x00}, /* DTMF_TONEXT2H */
  259 + { 0x34, 0x00}, /* DTMF_TONEXT2L */
  260 + { 0x35, 0x79}, /* DTMF_TONOFF */
  261 + { 0x36, 0x11}, /* DTMF_WANONOFF */
  262 + { 0x37, 0x00}, /* I2S_RX_SCRAMBLE_H */
  263 + { 0x38, 0x00}, /* I2S_RX_SCRAMBLE_M */
  264 + { 0x39, 0x00}, /* I2S_RX_SCRAMBLE_L */
  265 + { 0x3a, 0x06}, /* APLL_CTL */
  266 + { 0x3b, 0x00}, /* DTMF_CTL */
  267 + { 0x3c, 0x44}, /* DTMF_PGA_CTL2 (0x3C) */
  268 + { 0x3d, 0x69}, /* DTMF_PGA_CTL1 (0x3D) */
  269 + { 0x3e, 0x00}, /* MISC_SET_1 */
  270 + { 0x3f, 0x00}, /* PCMBTMUX */
  271 + /* 0x40 - 0x42 Unused */
  272 + { 0x43, 0x00}, /* RX_PATH_SEL */
  273 + { 0x44, 0x32}, /* VDL_APGA_CTL */
  274 + { 0x45, 0x00}, /* VIBRA_CTL */
  275 + { 0x46, 0x00}, /* VIBRA_SET */
  276 + { 0x47, 0x00}, /* VIBRA_PWM_SET */
  277 + { 0x48, 0x00}, /* ANAMIC_GAIN */
  278 + { 0x49, 0x00}, /* MISC_SET_2 */
  279 + /* End of Audio Registers */
  280 +};
  281 +
  282 +static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg)
  283 +{
  284 + switch (reg) {
  285 + case 0:
  286 + case 3:
  287 + case 40:
  288 + case 41:
  289 + case 42:
  290 + return false;
  291 + default:
  292 + return true;
  293 + }
  294 +}
  295 +
  296 +static const struct regmap_range twl4030_49_volatile_ranges[] = {
  297 + regmap_reg_range(TWL4030_BASEADD_TEST, 0xff),
  298 +};
  299 +
  300 +static const struct regmap_access_table twl4030_49_volatile_table = {
  301 + .yes_ranges = twl4030_49_volatile_ranges,
  302 + .n_yes_ranges = ARRAY_SIZE(twl4030_49_volatile_ranges),
  303 +};
  304 +
203 305 static struct regmap_config twl4030_regmap_config[4] = {
204 306 {
205 307 /* Address 0x48 */
... ... @@ -212,6 +314,15 @@
212 314 .reg_bits = 8,
213 315 .val_bits = 8,
214 316 .max_register = 0xff,
  317 +
  318 + .readable_reg = twl4030_49_nop_reg,
  319 + .writeable_reg = twl4030_49_nop_reg,
  320 +
  321 + .volatile_table = &twl4030_49_volatile_table,
  322 +
  323 + .reg_defaults = twl4030_49_defaults,
  324 + .num_reg_defaults = ARRAY_SIZE(twl4030_49_defaults),
  325 + .cache_type = REGCACHE_RBTREE,
215 326 },
216 327 {
217 328 /* Address 0x4a */
218 329  
219 330  
220 331  
221 332  
222 333  
223 334  
224 335  
225 336  
... ... @@ -302,36 +413,51 @@
302 413 EXPORT_SYMBOL(twl_rev);
303 414  
304 415 /**
305   - * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0
  416 + * twl_get_regmap - Get the regmap associated with the given module
306 417 * @mod_no: module number
307   - * @value: an array of num_bytes+1 containing data to write
308   - * @reg: register address (just offset will do)
309   - * @num_bytes: number of bytes to transfer
310 418 *
311   - * Returns the result of operation - 0 is success
  419 + * Returns the regmap pointer or NULL in case of failure.
312 420 */
313   -int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
  421 +static struct regmap *twl_get_regmap(u8 mod_no)
314 422 {
315   - int ret;
316 423 int sid;
317 424 struct twl_client *twl;
318 425  
319 426 if (unlikely(!twl_priv || !twl_priv->ready)) {
320 427 pr_err("%s: not initialized\n", DRIVER_NAME);
321   - return -EPERM;
  428 + return NULL;
322 429 }
323 430 if (unlikely(mod_no >= twl_get_last_module())) {
324 431 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
325   - return -EPERM;
  432 + return NULL;
326 433 }
327 434  
328 435 sid = twl_priv->twl_map[mod_no].sid;
329 436 twl = &twl_priv->twl_modules[sid];
330 437  
331   - ret = regmap_bulk_write(twl->regmap,
332   - twl_priv->twl_map[mod_no].base + reg, value,
333   - num_bytes);
  438 + return twl->regmap;
  439 +}
334 440  
  441 +/**
  442 + * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0
  443 + * @mod_no: module number
  444 + * @value: an array of num_bytes+1 containing data to write
  445 + * @reg: register address (just offset will do)
  446 + * @num_bytes: number of bytes to transfer
  447 + *
  448 + * Returns the result of operation - 0 is success
  449 + */
  450 +int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
  451 +{
  452 + struct regmap *regmap = twl_get_regmap(mod_no);
  453 + int ret;
  454 +
  455 + if (!regmap)
  456 + return -EPERM;
  457 +
  458 + ret = regmap_bulk_write(regmap, twl_priv->twl_map[mod_no].base + reg,
  459 + value, num_bytes);
  460 +
335 461 if (ret)
336 462 pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n",
337 463 DRIVER_NAME, mod_no, reg, num_bytes);
338 464  
339 465  
340 466  
341 467  
342 468  
... ... @@ -351,26 +477,15 @@
351 477 */
352 478 int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
353 479 {
  480 + struct regmap *regmap = twl_get_regmap(mod_no);
354 481 int ret;
355   - int sid;
356   - struct twl_client *twl;
357 482  
358   - if (unlikely(!twl_priv || !twl_priv->ready)) {
359   - pr_err("%s: not initialized\n", DRIVER_NAME);
  483 + if (!regmap)
360 484 return -EPERM;
361   - }
362   - if (unlikely(mod_no >= twl_get_last_module())) {
363   - pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
364   - return -EPERM;
365   - }
366 485  
367   - sid = twl_priv->twl_map[mod_no].sid;
368   - twl = &twl_priv->twl_modules[sid];
  486 + ret = regmap_bulk_read(regmap, twl_priv->twl_map[mod_no].base + reg,
  487 + value, num_bytes);
369 488  
370   - ret = regmap_bulk_read(twl->regmap,
371   - twl_priv->twl_map[mod_no].base + reg, value,
372   - num_bytes);
373   -
374 489 if (ret)
375 490 pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n",
376 491 DRIVER_NAME, mod_no, reg, num_bytes);
... ... @@ -378,6 +493,27 @@
378 493 return ret;
379 494 }
380 495 EXPORT_SYMBOL(twl_i2c_read);
  496 +
  497 +/**
  498 + * twl_regcache_bypass - Configure the regcache bypass for the regmap associated
  499 + * with the module
  500 + * @mod_no: module number
  501 + * @enable: Regcache bypass state
  502 + *
  503 + * Returns 0 else failure.
  504 + */
  505 +int twl_set_regcache_bypass(u8 mod_no, bool enable)
  506 +{
  507 + struct regmap *regmap = twl_get_regmap(mod_no);
  508 +
  509 + if (!regmap)
  510 + return -EPERM;
  511 +
  512 + regcache_cache_bypass(regmap, enable);
  513 +
  514 + return 0;
  515 +}
  516 +EXPORT_SYMBOL(twl_set_regcache_bypass);
381 517  
382 518 /*----------------------------------------------------------------------*/
383 519  
drivers/mfd/twl6040.c
... ... @@ -44,6 +44,54 @@
44 44 #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
45 45 #define TWL6040_NUM_SUPPLIES (2)
46 46  
  47 +static struct reg_default twl6040_defaults[] = {
  48 + { 0x01, 0x4B }, /* REG_ASICID (ro) */
  49 + { 0x02, 0x00 }, /* REG_ASICREV (ro) */
  50 + { 0x03, 0x00 }, /* REG_INTID */
  51 + { 0x04, 0x00 }, /* REG_INTMR */
  52 + { 0x05, 0x00 }, /* REG_NCPCTRL */
  53 + { 0x06, 0x00 }, /* REG_LDOCTL */
  54 + { 0x07, 0x60 }, /* REG_HPPLLCTL */
  55 + { 0x08, 0x00 }, /* REG_LPPLLCTL */
  56 + { 0x09, 0x4A }, /* REG_LPPLLDIV */
  57 + { 0x0A, 0x00 }, /* REG_AMICBCTL */
  58 + { 0x0B, 0x00 }, /* REG_DMICBCTL */
  59 + { 0x0C, 0x00 }, /* REG_MICLCTL */
  60 + { 0x0D, 0x00 }, /* REG_MICRCTL */
  61 + { 0x0E, 0x00 }, /* REG_MICGAIN */
  62 + { 0x0F, 0x1B }, /* REG_LINEGAIN */
  63 + { 0x10, 0x00 }, /* REG_HSLCTL */
  64 + { 0x11, 0x00 }, /* REG_HSRCTL */
  65 + { 0x12, 0x00 }, /* REG_HSGAIN */
  66 + { 0x13, 0x00 }, /* REG_EARCTL */
  67 + { 0x14, 0x00 }, /* REG_HFLCTL */
  68 + { 0x15, 0x00 }, /* REG_HFLGAIN */
  69 + { 0x16, 0x00 }, /* REG_HFRCTL */
  70 + { 0x17, 0x00 }, /* REG_HFRGAIN */
  71 + { 0x18, 0x00 }, /* REG_VIBCTLL */
  72 + { 0x19, 0x00 }, /* REG_VIBDATL */
  73 + { 0x1A, 0x00 }, /* REG_VIBCTLR */
  74 + { 0x1B, 0x00 }, /* REG_VIBDATR */
  75 + { 0x1C, 0x00 }, /* REG_HKCTL1 */
  76 + { 0x1D, 0x00 }, /* REG_HKCTL2 */
  77 + { 0x1E, 0x00 }, /* REG_GPOCTL */
  78 + { 0x1F, 0x00 }, /* REG_ALB */
  79 + { 0x20, 0x00 }, /* REG_DLB */
  80 + /* 0x28, REG_TRIM1 */
  81 + /* 0x29, REG_TRIM2 */
  82 + /* 0x2A, REG_TRIM3 */
  83 + /* 0x2B, REG_HSOTRIM */
  84 + /* 0x2C, REG_HFOTRIM */
  85 + { 0x2D, 0x08 }, /* REG_ACCCTL */
  86 + { 0x2E, 0x00 }, /* REG_STATUS (ro) */
  87 +};
  88 +
  89 +struct reg_default twl6040_patch[] = {
  90 + /* Select I2C bus access to dual access registers */
  91 + { TWL6040_REG_ACCCTL, 0x09 },
  92 +};
  93 +
  94 +
47 95 static bool twl6040_has_vibra(struct device_node *node)
48 96 {
49 97 #ifdef CONFIG_OF
... ... @@ -238,6 +286,9 @@
238 286 if (twl6040->power_count++)
239 287 goto out;
240 288  
  289 + /* Allow writes to the chip */
  290 + regcache_cache_only(twl6040->regmap, false);
  291 +
241 292 if (gpio_is_valid(twl6040->audpwron)) {
242 293 /* use automatic power-up sequence */
243 294 ret = twl6040_power_up_automatic(twl6040);
... ... @@ -253,6 +304,10 @@
253 304 goto out;
254 305 }
255 306 }
  307 +
  308 + /* Sync with the HW */
  309 + regcache_sync(twl6040->regmap);
  310 +
256 311 /* Default PLL configuration after power up */
257 312 twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
258 313 twl6040->sysclk = 19200000;
... ... @@ -279,6 +334,11 @@
279 334 /* use manual power-down sequence */
280 335 twl6040_power_down_manual(twl6040);
281 336 }
  337 +
  338 + /* Set regmap to cache only and mark it as dirty */
  339 + regcache_cache_only(twl6040->regmap, true);
  340 + regcache_mark_dirty(twl6040->regmap);
  341 +
282 342 twl6040->sysclk = 0;
283 343 twl6040->mclk = 0;
284 344 }
285 345  
... ... @@ -490,10 +550,25 @@
490 550 static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
491 551 {
492 552 switch (reg) {
493   - case TWL6040_REG_VIBCTLL:
494   - case TWL6040_REG_VIBCTLR:
495   - case TWL6040_REG_INTMR:
  553 + case TWL6040_REG_ASICID:
  554 + case TWL6040_REG_ASICREV:
  555 + case TWL6040_REG_INTID:
  556 + case TWL6040_REG_LPPLLCTL:
  557 + case TWL6040_REG_HPPLLCTL:
  558 + case TWL6040_REG_STATUS:
  559 + return true;
  560 + default:
496 561 return false;
  562 + }
  563 +}
  564 +
  565 +static bool twl6040_writeable_reg(struct device *dev, unsigned int reg)
  566 +{
  567 + switch (reg) {
  568 + case TWL6040_REG_ASICID:
  569 + case TWL6040_REG_ASICREV:
  570 + case TWL6040_REG_STATUS:
  571 + return false;
497 572 default:
498 573 return true;
499 574 }
500 575  
... ... @@ -502,10 +577,15 @@
502 577 static struct regmap_config twl6040_regmap_config = {
503 578 .reg_bits = 8,
504 579 .val_bits = 8,
  580 +
  581 + .reg_defaults = twl6040_defaults,
  582 + .num_reg_defaults = ARRAY_SIZE(twl6040_defaults),
  583 +
505 584 .max_register = TWL6040_REG_STATUS, /* 0x2e */
506 585  
507 586 .readable_reg = twl6040_readable_reg,
508 587 .volatile_reg = twl6040_volatile_reg,
  588 + .writeable_reg = twl6040_writeable_reg,
509 589  
510 590 .cache_type = REGCACHE_RBTREE,
511 591 };
... ... @@ -624,6 +704,8 @@
624 704  
625 705 /* dual-access registers controlled by I2C only */
626 706 twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);
  707 + regmap_register_patch(twl6040->regmap, twl6040_patch,
  708 + ARRAY_SIZE(twl6040_patch));
627 709  
628 710 /*
629 711 * The main functionality of twl6040 to provide audio on OMAP4+ systems.
... ... @@ -655,6 +737,10 @@
655 737 cell = &twl6040->cells[children];
656 738 cell->name = "twl6040-gpo";
657 739 children++;
  740 +
  741 + /* The chip is powered down so mark regmap to cache only and dirty */
  742 + regcache_cache_only(twl6040->regmap, true);
  743 + regcache_mark_dirty(twl6040->regmap);
658 744  
659 745 ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
660 746 NULL, 0, NULL);
include/linux/i2c/twl.h
... ... @@ -175,6 +175,9 @@
175 175 TWL_CLASS_IS(4030, TWL4030_CLASS_ID)
176 176 TWL_CLASS_IS(6030, TWL6030_CLASS_ID)
177 177  
  178 +/* Set the regcache bypass for the regmap associated with the nodule */
  179 +int twl_set_regcache_bypass(u8 mod_no, bool enable);
  180 +
178 181 /*
179 182 * Read and write several 8-bit registers at once.
180 183 */