aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2014-01-21 03:26:12 -0500
committerLee Jones <lee.jones@linaro.org>2014-01-21 03:26:12 -0500
commit09fd19da0074b86030a00303522b2ba63a4399b7 (patch)
treed0b6d79cda4a26c9a2e4ca2f4a9fdaaaea9e640a /drivers/mfd
parent6eb37eb276f0b91adb43b853ce6fb0812fbf0883 (diff)
parent9146070089cca0fa5c396f1a4d0b96d675004c04 (diff)
Merge tag 'ib-asoc-3.14.2' into for-mfd-next
Immutable branch between MFD and ASoC due for the v3.14 merge window
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/twl-core.c190
-rw-r--r--drivers/mfd/twl6040.c92
2 files changed, 252 insertions, 30 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index f0aa4cef9ad0..ed718328eff1 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -47,6 +47,9 @@
47#include <linux/i2c.h> 47#include <linux/i2c.h>
48#include <linux/i2c/twl.h> 48#include <linux/i2c/twl.h>
49 49
50/* Register descriptions for audio */
51#include <linux/mfd/twl4030-audio.h>
52
50#include "twl-core.h" 53#include "twl-core.h"
51 54
52/* 55/*
@@ -200,6 +203,105 @@ static struct twl_mapping twl4030_map[] = {
200 { 2, TWL5031_BASEADD_INTERRUPTS }, 203 { 2, TWL5031_BASEADD_INTERRUPTS },
201}; 204};
202 205
206static 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
282static 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
296static const struct regmap_range twl4030_49_volatile_ranges[] = {
297 regmap_reg_range(TWL4030_BASEADD_TEST, 0xff),
298};
299
300static 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
203static struct regmap_config twl4030_regmap_config[4] = { 305static struct regmap_config twl4030_regmap_config[4] = {
204 { 306 {
205 /* Address 0x48 */ 307 /* Address 0x48 */
@@ -212,6 +314,15 @@ static struct regmap_config twl4030_regmap_config[4] = {
212 .reg_bits = 8, 314 .reg_bits = 8,
213 .val_bits = 8, 315 .val_bits = 8,
214 .max_register = 0xff, 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 /* Address 0x4a */ 328 /* Address 0x4a */
@@ -302,35 +413,50 @@ unsigned int twl_rev(void)
302EXPORT_SYMBOL(twl_rev); 413EXPORT_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 * @mod_no: module number 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 */
313int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) 421static struct regmap *twl_get_regmap(u8 mod_no)
314{ 422{
315 int ret;
316 int sid; 423 int sid;
317 struct twl_client *twl; 424 struct twl_client *twl;
318 425
319 if (unlikely(!twl_priv || !twl_priv->ready)) { 426 if (unlikely(!twl_priv || !twl_priv->ready)) {
320 pr_err("%s: not initialized\n", DRIVER_NAME); 427 pr_err("%s: not initialized\n", DRIVER_NAME);
321 return -EPERM; 428 return NULL;
322 } 429 }
323 if (unlikely(mod_no >= twl_get_last_module())) { 430 if (unlikely(mod_no >= twl_get_last_module())) {
324 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); 431 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
325 return -EPERM; 432 return NULL;
326 } 433 }
327 434
328 sid = twl_priv->twl_map[mod_no].sid; 435 sid = twl_priv->twl_map[mod_no].sid;
329 twl = &twl_priv->twl_modules[sid]; 436 twl = &twl_priv->twl_modules[sid];
330 437
331 ret = regmap_bulk_write(twl->regmap, 438 return twl->regmap;
332 twl_priv->twl_map[mod_no].base + reg, value, 439}
333 num_bytes); 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 */
450int 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);
334 460
335 if (ret) 461 if (ret)
336 pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n", 462 pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n",
@@ -351,25 +477,14 @@ EXPORT_SYMBOL(twl_i2c_write);
351 */ 477 */
352int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) 478int 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 int ret; 481 int ret;
355 int sid;
356 struct twl_client *twl;
357 482
358 if (unlikely(!twl_priv || !twl_priv->ready)) { 483 if (!regmap)
359 pr_err("%s: not initialized\n", DRIVER_NAME);
360 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; 484 return -EPERM;
365 }
366
367 sid = twl_priv->twl_map[mod_no].sid;
368 twl = &twl_priv->twl_modules[sid];
369 485
370 ret = regmap_bulk_read(twl->regmap, 486 ret = regmap_bulk_read(regmap, twl_priv->twl_map[mod_no].base + reg,
371 twl_priv->twl_map[mod_no].base + reg, value, 487 value, num_bytes);
372 num_bytes);
373 488
374 if (ret) 489 if (ret)
375 pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n", 490 pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n",
@@ -379,6 +494,27 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
379} 494}
380EXPORT_SYMBOL(twl_i2c_read); 495EXPORT_SYMBOL(twl_i2c_read);
381 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 */
505int 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}
516EXPORT_SYMBOL(twl_set_regcache_bypass);
517
382/*----------------------------------------------------------------------*/ 518/*----------------------------------------------------------------------*/
383 519
384/** 520/**
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index 0779d5ab9ab1..51b6df1a7949 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -44,6 +44,54 @@
44#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) 44#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
45#define TWL6040_NUM_SUPPLIES (2) 45#define TWL6040_NUM_SUPPLIES (2)
46 46
47static 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
89struct reg_default twl6040_patch[] = {
90 /* Select I2C bus access to dual access registers */
91 { TWL6040_REG_ACCCTL, 0x09 },
92};
93
94
47static bool twl6040_has_vibra(struct device_node *node) 95static bool twl6040_has_vibra(struct device_node *node)
48{ 96{
49#ifdef CONFIG_OF 97#ifdef CONFIG_OF
@@ -238,6 +286,9 @@ int twl6040_power(struct twl6040 *twl6040, int on)
238 if (twl6040->power_count++) 286 if (twl6040->power_count++)
239 goto out; 287 goto out;
240 288
289 /* Allow writes to the chip */
290 regcache_cache_only(twl6040->regmap, false);
291
241 if (gpio_is_valid(twl6040->audpwron)) { 292 if (gpio_is_valid(twl6040->audpwron)) {
242 /* use automatic power-up sequence */ 293 /* use automatic power-up sequence */
243 ret = twl6040_power_up_automatic(twl6040); 294 ret = twl6040_power_up_automatic(twl6040);
@@ -253,6 +304,10 @@ int twl6040_power(struct twl6040 *twl6040, int on)
253 goto out; 304 goto out;
254 } 305 }
255 } 306 }
307
308 /* Sync with the HW */
309 regcache_sync(twl6040->regmap);
310
256 /* Default PLL configuration after power up */ 311 /* Default PLL configuration after power up */
257 twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; 312 twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
258 twl6040->sysclk = 19200000; 313 twl6040->sysclk = 19200000;
@@ -279,6 +334,11 @@ int twl6040_power(struct twl6040 *twl6040, int on)
279 /* use manual power-down sequence */ 334 /* use manual power-down sequence */
280 twl6040_power_down_manual(twl6040); 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 twl6040->sysclk = 0; 342 twl6040->sysclk = 0;
283 twl6040->mclk = 0; 343 twl6040->mclk = 0;
284 } 344 }
@@ -490,9 +550,24 @@ static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
490static bool twl6040_volatile_reg(struct device *dev, unsigned int reg) 550static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
491{ 551{
492 switch (reg) { 552 switch (reg) {
493 case TWL6040_REG_VIBCTLL: 553 case TWL6040_REG_ASICID:
494 case TWL6040_REG_VIBCTLR: 554 case TWL6040_REG_ASICREV:
495 case TWL6040_REG_INTMR: 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:
561 return false;
562 }
563}
564
565static 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:
496 return false; 571 return false;
497 default: 572 default:
498 return true; 573 return true;
@@ -502,10 +577,15 @@ static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
502static struct regmap_config twl6040_regmap_config = { 577static struct regmap_config twl6040_regmap_config = {
503 .reg_bits = 8, 578 .reg_bits = 8,
504 .val_bits = 8, 579 .val_bits = 8,
580
581 .reg_defaults = twl6040_defaults,
582 .num_reg_defaults = ARRAY_SIZE(twl6040_defaults),
583
505 .max_register = TWL6040_REG_STATUS, /* 0x2e */ 584 .max_register = TWL6040_REG_STATUS, /* 0x2e */
506 585
507 .readable_reg = twl6040_readable_reg, 586 .readable_reg = twl6040_readable_reg,
508 .volatile_reg = twl6040_volatile_reg, 587 .volatile_reg = twl6040_volatile_reg,
588 .writeable_reg = twl6040_writeable_reg,
509 589
510 .cache_type = REGCACHE_RBTREE, 590 .cache_type = REGCACHE_RBTREE,
511}; 591};
@@ -624,6 +704,8 @@ static int twl6040_probe(struct i2c_client *client,
624 704
625 /* dual-access registers controlled by I2C only */ 705 /* dual-access registers controlled by I2C only */
626 twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL); 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 * The main functionality of twl6040 to provide audio on OMAP4+ systems. 711 * The main functionality of twl6040 to provide audio on OMAP4+ systems.
@@ -656,6 +738,10 @@ static int twl6040_probe(struct i2c_client *client,
656 cell->name = "twl6040-gpo"; 738 cell->name = "twl6040-gpo";
657 children++; 739 children++;
658 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);
744
659 ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, 745 ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
660 NULL, 0, NULL); 746 NULL, 0, NULL);
661 if (ret) 747 if (ret)