diff options
Diffstat (limited to 'drivers/mfd')
32 files changed, 1079 insertions, 531 deletions
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index 391e23e6a647..582bda543520 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c | |||
@@ -531,7 +531,7 @@ static int pm800_probe(struct i2c_client *client, | |||
531 | ret = device_800_init(chip, pdata); | 531 | ret = device_800_init(chip, pdata); |
532 | if (ret) { | 532 | if (ret) { |
533 | dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id); | 533 | dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id); |
534 | goto err_800_init; | 534 | goto err_subchip_alloc; |
535 | } | 535 | } |
536 | 536 | ||
537 | ret = pm800_pages_init(chip); | 537 | ret = pm800_pages_init(chip); |
@@ -546,10 +546,8 @@ static int pm800_probe(struct i2c_client *client, | |||
546 | err_page_init: | 546 | err_page_init: |
547 | mfd_remove_devices(chip->dev); | 547 | mfd_remove_devices(chip->dev); |
548 | device_irq_exit_800(chip); | 548 | device_irq_exit_800(chip); |
549 | err_800_init: | ||
550 | devm_kfree(&client->dev, subchip); | ||
551 | err_subchip_alloc: | 549 | err_subchip_alloc: |
552 | pm80x_deinit(client); | 550 | pm80x_deinit(); |
553 | out_init: | 551 | out_init: |
554 | return ret; | 552 | return ret; |
555 | } | 553 | } |
@@ -562,9 +560,7 @@ static int pm800_remove(struct i2c_client *client) | |||
562 | device_irq_exit_800(chip); | 560 | device_irq_exit_800(chip); |
563 | 561 | ||
564 | pm800_pages_exit(chip); | 562 | pm800_pages_exit(chip); |
565 | devm_kfree(&client->dev, chip->subchip); | 563 | pm80x_deinit(); |
566 | |||
567 | pm80x_deinit(client); | ||
568 | 564 | ||
569 | return 0; | 565 | return 0; |
570 | } | 566 | } |
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index e671230be2b1..65d7ac099b20 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c | |||
@@ -257,7 +257,7 @@ static int pm805_probe(struct i2c_client *client, | |||
257 | pdata->plat_config(chip, pdata); | 257 | pdata->plat_config(chip, pdata); |
258 | 258 | ||
259 | err_805_init: | 259 | err_805_init: |
260 | pm80x_deinit(client); | 260 | pm80x_deinit(); |
261 | out_init: | 261 | out_init: |
262 | return ret; | 262 | return ret; |
263 | } | 263 | } |
@@ -269,7 +269,7 @@ static int pm805_remove(struct i2c_client *client) | |||
269 | mfd_remove_devices(chip->dev); | 269 | mfd_remove_devices(chip->dev); |
270 | device_irq_exit_805(chip); | 270 | device_irq_exit_805(chip); |
271 | 271 | ||
272 | pm80x_deinit(client); | 272 | pm80x_deinit(); |
273 | 273 | ||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c index 1adb355d86d1..f736a46eb8c0 100644 --- a/drivers/mfd/88pm80x.c +++ b/drivers/mfd/88pm80x.c | |||
@@ -48,14 +48,12 @@ int pm80x_init(struct i2c_client *client, | |||
48 | ret = PTR_ERR(map); | 48 | ret = PTR_ERR(map); |
49 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | 49 | dev_err(&client->dev, "Failed to allocate register map: %d\n", |
50 | ret); | 50 | ret); |
51 | goto err_regmap_init; | 51 | return ret; |
52 | } | 52 | } |
53 | 53 | ||
54 | chip->id = id->driver_data; | 54 | chip->id = id->driver_data; |
55 | if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805) { | 55 | if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805) |
56 | ret = -EINVAL; | 56 | return -EINVAL; |
57 | goto err_chip_id; | ||
58 | } | ||
59 | 57 | ||
60 | chip->client = client; | 58 | chip->client = client; |
61 | chip->regmap = map; | 59 | chip->regmap = map; |
@@ -82,19 +80,11 @@ int pm80x_init(struct i2c_client *client, | |||
82 | } | 80 | } |
83 | 81 | ||
84 | return 0; | 82 | return 0; |
85 | |||
86 | err_chip_id: | ||
87 | regmap_exit(map); | ||
88 | err_regmap_init: | ||
89 | devm_kfree(&client->dev, chip); | ||
90 | return ret; | ||
91 | } | 83 | } |
92 | EXPORT_SYMBOL_GPL(pm80x_init); | 84 | EXPORT_SYMBOL_GPL(pm80x_init); |
93 | 85 | ||
94 | int pm80x_deinit(struct i2c_client *client) | 86 | int pm80x_deinit(void) |
95 | { | 87 | { |
96 | struct pm80x_chip *chip = i2c_get_clientdata(client); | ||
97 | |||
98 | /* | 88 | /* |
99 | * workaround: clear the dependency between pm800 and pm805. | 89 | * workaround: clear the dependency between pm800 and pm805. |
100 | * would remove it after HW chip fixes the issue. | 90 | * would remove it after HW chip fixes the issue. |
@@ -103,10 +93,6 @@ int pm80x_deinit(struct i2c_client *client) | |||
103 | g_pm80x_chip->companion = NULL; | 93 | g_pm80x_chip->companion = NULL; |
104 | else | 94 | else |
105 | g_pm80x_chip = NULL; | 95 | g_pm80x_chip = NULL; |
106 | |||
107 | regmap_exit(chip->regmap); | ||
108 | devm_kfree(&client->dev, chip); | ||
109 | |||
110 | return 0; | 96 | return 0; |
111 | } | 97 | } |
112 | EXPORT_SYMBOL_GPL(pm80x_deinit); | 98 | EXPORT_SYMBOL_GPL(pm80x_deinit); |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 47ad4e270877..ff553babf455 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -237,6 +237,7 @@ config MFD_TPS65910 | |||
237 | depends on I2C=y && GPIOLIB | 237 | depends on I2C=y && GPIOLIB |
238 | select MFD_CORE | 238 | select MFD_CORE |
239 | select REGMAP_I2C | 239 | select REGMAP_I2C |
240 | select REGMAP_IRQ | ||
240 | select IRQ_DOMAIN | 241 | select IRQ_DOMAIN |
241 | help | 242 | help |
242 | if you say yes here you get support for the TPS65910 series of | 243 | if you say yes here you get support for the TPS65910 series of |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 8b977f8045ae..b90409c23664 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -9,7 +9,7 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o | |||
9 | obj-$(CONFIG_MFD_SM501) += sm501.o | 9 | obj-$(CONFIG_MFD_SM501) += sm501.o |
10 | obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o | 10 | obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o |
11 | 11 | ||
12 | rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o | 12 | rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o |
13 | obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o | 13 | obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o |
14 | 14 | ||
15 | obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o | 15 | obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 05a7af4b9768..104514228b74 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
20 | #include <linux/mfd/abx500.h> | 20 | #include <linux/mfd/abx500.h> |
21 | #include <linux/mfd/abx500/ab8500.h> | 21 | #include <linux/mfd/abx500/ab8500.h> |
22 | #include <linux/mfd/abx500/ab8500-bm.h> | ||
22 | #include <linux/mfd/dbx500-prcmu.h> | 23 | #include <linux/mfd/dbx500-prcmu.h> |
23 | #include <linux/regulator/ab8500.h> | 24 | #include <linux/regulator/ab8500.h> |
24 | #include <linux/of.h> | 25 | #include <linux/of.h> |
@@ -924,7 +925,7 @@ static struct resource ab8505_iddet_resources[] = { | |||
924 | 925 | ||
925 | static struct resource ab8500_temp_resources[] = { | 926 | static struct resource ab8500_temp_resources[] = { |
926 | { | 927 | { |
927 | .name = "AB8500_TEMP_WARM", | 928 | .name = "ABX500_TEMP_WARM", |
928 | .start = AB8500_INT_TEMP_WARM, | 929 | .start = AB8500_INT_TEMP_WARM, |
929 | .end = AB8500_INT_TEMP_WARM, | 930 | .end = AB8500_INT_TEMP_WARM, |
930 | .flags = IORESOURCE_IRQ, | 931 | .flags = IORESOURCE_IRQ, |
@@ -1000,8 +1001,8 @@ static struct mfd_cell abx500_common_devs[] = { | |||
1000 | .of_compatible = "stericsson,ab8500-denc", | 1001 | .of_compatible = "stericsson,ab8500-denc", |
1001 | }, | 1002 | }, |
1002 | { | 1003 | { |
1003 | .name = "ab8500-temp", | 1004 | .name = "abx500-temp", |
1004 | .of_compatible = "stericsson,ab8500-temp", | 1005 | .of_compatible = "stericsson,abx500-temp", |
1005 | .num_resources = ARRAY_SIZE(ab8500_temp_resources), | 1006 | .num_resources = ARRAY_SIZE(ab8500_temp_resources), |
1006 | .resources = ab8500_temp_resources, | 1007 | .resources = ab8500_temp_resources, |
1007 | }, | 1008 | }, |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index bc8a3edb6bbf..b562c7bf8a46 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -115,7 +115,7 @@ static irqreturn_t arizona_underclocked(int irq, void *data) | |||
115 | if (val & ARIZONA_ADC_UNDERCLOCKED_STS) | 115 | if (val & ARIZONA_ADC_UNDERCLOCKED_STS) |
116 | dev_err(arizona->dev, "ADC underclocked\n"); | 116 | dev_err(arizona->dev, "ADC underclocked\n"); |
117 | if (val & ARIZONA_MIXER_UNDERCLOCKED_STS) | 117 | if (val & ARIZONA_MIXER_UNDERCLOCKED_STS) |
118 | dev_err(arizona->dev, "Mixer underclocked\n"); | 118 | dev_err(arizona->dev, "Mixer dropped sample\n"); |
119 | 119 | ||
120 | return IRQ_HANDLED; | 120 | return IRQ_HANDLED; |
121 | } | 121 | } |
@@ -239,7 +239,12 @@ static int arizona_runtime_resume(struct device *dev) | |||
239 | return ret; | 239 | return ret; |
240 | } | 240 | } |
241 | 241 | ||
242 | regcache_sync(arizona->regmap); | 242 | ret = regcache_sync(arizona->regmap); |
243 | if (ret != 0) { | ||
244 | dev_err(arizona->dev, "Failed to restore register cache\n"); | ||
245 | regulator_disable(arizona->dcvdd); | ||
246 | return ret; | ||
247 | } | ||
243 | 248 | ||
244 | return 0; | 249 | return 0; |
245 | } | 250 | } |
@@ -258,10 +263,36 @@ static int arizona_runtime_suspend(struct device *dev) | |||
258 | } | 263 | } |
259 | #endif | 264 | #endif |
260 | 265 | ||
266 | #ifdef CONFIG_PM_SLEEP | ||
267 | static int arizona_resume_noirq(struct device *dev) | ||
268 | { | ||
269 | struct arizona *arizona = dev_get_drvdata(dev); | ||
270 | |||
271 | dev_dbg(arizona->dev, "Early resume, disabling IRQ\n"); | ||
272 | disable_irq(arizona->irq); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | static int arizona_resume(struct device *dev) | ||
278 | { | ||
279 | struct arizona *arizona = dev_get_drvdata(dev); | ||
280 | |||
281 | dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n"); | ||
282 | enable_irq(arizona->irq); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | #endif | ||
287 | |||
261 | const struct dev_pm_ops arizona_pm_ops = { | 288 | const struct dev_pm_ops arizona_pm_ops = { |
262 | SET_RUNTIME_PM_OPS(arizona_runtime_suspend, | 289 | SET_RUNTIME_PM_OPS(arizona_runtime_suspend, |
263 | arizona_runtime_resume, | 290 | arizona_runtime_resume, |
264 | NULL) | 291 | NULL) |
292 | SET_SYSTEM_SLEEP_PM_OPS(NULL, arizona_resume) | ||
293 | #ifdef CONFIG_PM_SLEEP | ||
294 | .resume_noirq = arizona_resume_noirq, | ||
295 | #endif | ||
265 | }; | 296 | }; |
266 | EXPORT_SYMBOL_GPL(arizona_pm_ops); | 297 | EXPORT_SYMBOL_GPL(arizona_pm_ops); |
267 | 298 | ||
@@ -270,19 +301,19 @@ static struct mfd_cell early_devs[] = { | |||
270 | }; | 301 | }; |
271 | 302 | ||
272 | static struct mfd_cell wm5102_devs[] = { | 303 | static struct mfd_cell wm5102_devs[] = { |
304 | { .name = "arizona-micsupp" }, | ||
273 | { .name = "arizona-extcon" }, | 305 | { .name = "arizona-extcon" }, |
274 | { .name = "arizona-gpio" }, | 306 | { .name = "arizona-gpio" }, |
275 | { .name = "arizona-haptics" }, | 307 | { .name = "arizona-haptics" }, |
276 | { .name = "arizona-micsupp" }, | ||
277 | { .name = "arizona-pwm" }, | 308 | { .name = "arizona-pwm" }, |
278 | { .name = "wm5102-codec" }, | 309 | { .name = "wm5102-codec" }, |
279 | }; | 310 | }; |
280 | 311 | ||
281 | static struct mfd_cell wm5110_devs[] = { | 312 | static struct mfd_cell wm5110_devs[] = { |
313 | { .name = "arizona-micsupp" }, | ||
282 | { .name = "arizona-extcon" }, | 314 | { .name = "arizona-extcon" }, |
283 | { .name = "arizona-gpio" }, | 315 | { .name = "arizona-gpio" }, |
284 | { .name = "arizona-haptics" }, | 316 | { .name = "arizona-haptics" }, |
285 | { .name = "arizona-micsupp" }, | ||
286 | { .name = "arizona-pwm" }, | 317 | { .name = "arizona-pwm" }, |
287 | { .name = "wm5110-codec" }, | 318 | { .name = "wm5110-codec" }, |
288 | }; | 319 | }; |
@@ -479,6 +510,29 @@ int arizona_dev_init(struct arizona *arizona) | |||
479 | goto err_reset; | 510 | goto err_reset; |
480 | } | 511 | } |
481 | 512 | ||
513 | for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) { | ||
514 | if (!arizona->pdata.micbias[i].mV) | ||
515 | continue; | ||
516 | |||
517 | val = (arizona->pdata.micbias[i].mV - 1500) / 100; | ||
518 | val <<= ARIZONA_MICB1_LVL_SHIFT; | ||
519 | |||
520 | if (arizona->pdata.micbias[i].ext_cap) | ||
521 | val |= ARIZONA_MICB1_EXT_CAP; | ||
522 | |||
523 | if (arizona->pdata.micbias[i].discharge) | ||
524 | val |= ARIZONA_MICB1_DISCH; | ||
525 | |||
526 | if (arizona->pdata.micbias[i].fast_start) | ||
527 | val |= ARIZONA_MICB1_RATE; | ||
528 | |||
529 | regmap_update_bits(arizona->regmap, | ||
530 | ARIZONA_MIC_BIAS_CTRL_1 + i, | ||
531 | ARIZONA_MICB1_LVL_MASK | | ||
532 | ARIZONA_MICB1_DISCH | | ||
533 | ARIZONA_MICB1_RATE, val); | ||
534 | } | ||
535 | |||
482 | for (i = 0; i < ARIZONA_MAX_INPUT; i++) { | 536 | for (i = 0; i < ARIZONA_MAX_INPUT; i++) { |
483 | /* Default for both is 0 so noop with defaults */ | 537 | /* Default for both is 0 so noop with defaults */ |
484 | val = arizona->pdata.dmic_ref[i] | 538 | val = arizona->pdata.dmic_ref[i] |
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 74713bf5371f..2bec5f0db3ee 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c | |||
@@ -176,14 +176,7 @@ int arizona_irq_init(struct arizona *arizona) | |||
176 | aod = &wm5102_aod; | 176 | aod = &wm5102_aod; |
177 | irq = &wm5102_irq; | 177 | irq = &wm5102_irq; |
178 | 178 | ||
179 | switch (arizona->rev) { | 179 | ctrlif_error = false; |
180 | case 0: | ||
181 | case 1: | ||
182 | ctrlif_error = false; | ||
183 | break; | ||
184 | default: | ||
185 | break; | ||
186 | } | ||
187 | break; | 180 | break; |
188 | #endif | 181 | #endif |
189 | #ifdef CONFIG_MFD_WM5110 | 182 | #ifdef CONFIG_MFD_WM5110 |
@@ -191,14 +184,7 @@ int arizona_irq_init(struct arizona *arizona) | |||
191 | aod = &wm5110_aod; | 184 | aod = &wm5110_aod; |
192 | irq = &wm5110_irq; | 185 | irq = &wm5110_irq; |
193 | 186 | ||
194 | switch (arizona->rev) { | 187 | ctrlif_error = false; |
195 | case 0: | ||
196 | case 1: | ||
197 | ctrlif_error = false; | ||
198 | break; | ||
199 | default: | ||
200 | break; | ||
201 | } | ||
202 | break; | 188 | break; |
203 | #endif | 189 | #endif |
204 | default: | 190 | default: |
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index ac74a4d1daea..885e56780358 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c | |||
@@ -27,6 +27,66 @@ | |||
27 | #include <linux/of_device.h> | 27 | #include <linux/of_device.h> |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | /* I2C safe register check */ | ||
31 | static inline bool i2c_safe_reg(unsigned char reg) | ||
32 | { | ||
33 | switch (reg) { | ||
34 | case DA9052_STATUS_A_REG: | ||
35 | case DA9052_STATUS_B_REG: | ||
36 | case DA9052_STATUS_C_REG: | ||
37 | case DA9052_STATUS_D_REG: | ||
38 | case DA9052_ADC_RES_L_REG: | ||
39 | case DA9052_ADC_RES_H_REG: | ||
40 | case DA9052_VDD_RES_REG: | ||
41 | case DA9052_ICHG_AV_REG: | ||
42 | case DA9052_TBAT_RES_REG: | ||
43 | case DA9052_ADCIN4_RES_REG: | ||
44 | case DA9052_ADCIN5_RES_REG: | ||
45 | case DA9052_ADCIN6_RES_REG: | ||
46 | case DA9052_TJUNC_RES_REG: | ||
47 | case DA9052_TSI_X_MSB_REG: | ||
48 | case DA9052_TSI_Y_MSB_REG: | ||
49 | case DA9052_TSI_LSB_REG: | ||
50 | case DA9052_TSI_Z_MSB_REG: | ||
51 | return true; | ||
52 | default: | ||
53 | return false; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * There is an issue with DA9052 and DA9053_AA/BA/BB PMIC where the PMIC | ||
59 | * gets lockup up or fails to respond following a system reset. | ||
60 | * This fix is to follow any read or write with a dummy read to a safe | ||
61 | * register. | ||
62 | */ | ||
63 | int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg) | ||
64 | { | ||
65 | int val; | ||
66 | |||
67 | switch (da9052->chip_id) { | ||
68 | case DA9052: | ||
69 | case DA9053_AA: | ||
70 | case DA9053_BA: | ||
71 | case DA9053_BB: | ||
72 | /* A dummy read to a safe register address. */ | ||
73 | if (!i2c_safe_reg(reg)) | ||
74 | return regmap_read(da9052->regmap, | ||
75 | DA9052_PARK_REGISTER, | ||
76 | &val); | ||
77 | break; | ||
78 | default: | ||
79 | /* | ||
80 | * For other chips parking of I2C register | ||
81 | * to a safe place is not required. | ||
82 | */ | ||
83 | break; | ||
84 | } | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | EXPORT_SYMBOL(da9052_i2c_fix); | ||
89 | |||
30 | static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) | 90 | static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) |
31 | { | 91 | { |
32 | int reg_val, ret; | 92 | int reg_val, ret; |
@@ -83,6 +143,7 @@ static int da9052_i2c_probe(struct i2c_client *client, | |||
83 | 143 | ||
84 | da9052->dev = &client->dev; | 144 | da9052->dev = &client->dev; |
85 | da9052->chip_irq = client->irq; | 145 | da9052->chip_irq = client->irq; |
146 | da9052->fix_io = da9052_i2c_fix; | ||
86 | 147 | ||
87 | i2c_set_clientdata(client, da9052); | 148 | i2c_set_clientdata(client, da9052); |
88 | 149 | ||
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index dc8826d8d69d..e42a417adc5f 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/regulator/db8500-prcmu.h> | 32 | #include <linux/regulator/db8500-prcmu.h> |
33 | #include <linux/regulator/machine.h> | 33 | #include <linux/regulator/machine.h> |
34 | #include <linux/cpufreq.h> | 34 | #include <linux/cpufreq.h> |
35 | #include <linux/platform_data/ux500_wdt.h> | ||
35 | #include <asm/hardware/gic.h> | 36 | #include <asm/hardware/gic.h> |
36 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
37 | #include <mach/irqs.h> | 38 | #include <mach/irqs.h> |
@@ -2212,21 +2213,25 @@ int db8500_prcmu_config_a9wdog(u8 num, bool sleep_auto_off) | |||
2212 | sleep_auto_off ? A9WDOG_AUTO_OFF_EN : | 2213 | sleep_auto_off ? A9WDOG_AUTO_OFF_EN : |
2213 | A9WDOG_AUTO_OFF_DIS); | 2214 | A9WDOG_AUTO_OFF_DIS); |
2214 | } | 2215 | } |
2216 | EXPORT_SYMBOL(db8500_prcmu_config_a9wdog); | ||
2215 | 2217 | ||
2216 | int db8500_prcmu_enable_a9wdog(u8 id) | 2218 | int db8500_prcmu_enable_a9wdog(u8 id) |
2217 | { | 2219 | { |
2218 | return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0); | 2220 | return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0); |
2219 | } | 2221 | } |
2222 | EXPORT_SYMBOL(db8500_prcmu_enable_a9wdog); | ||
2220 | 2223 | ||
2221 | int db8500_prcmu_disable_a9wdog(u8 id) | 2224 | int db8500_prcmu_disable_a9wdog(u8 id) |
2222 | { | 2225 | { |
2223 | return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0); | 2226 | return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0); |
2224 | } | 2227 | } |
2228 | EXPORT_SYMBOL(db8500_prcmu_disable_a9wdog); | ||
2225 | 2229 | ||
2226 | int db8500_prcmu_kick_a9wdog(u8 id) | 2230 | int db8500_prcmu_kick_a9wdog(u8 id) |
2227 | { | 2231 | { |
2228 | return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0); | 2232 | return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0); |
2229 | } | 2233 | } |
2234 | EXPORT_SYMBOL(db8500_prcmu_kick_a9wdog); | ||
2230 | 2235 | ||
2231 | /* | 2236 | /* |
2232 | * timeout is 28 bit, in ms. | 2237 | * timeout is 28 bit, in ms. |
@@ -2244,6 +2249,7 @@ int db8500_prcmu_load_a9wdog(u8 id, u32 timeout) | |||
2244 | (u8)((timeout >> 12) & 0xff), | 2249 | (u8)((timeout >> 12) & 0xff), |
2245 | (u8)((timeout >> 20) & 0xff)); | 2250 | (u8)((timeout >> 20) & 0xff)); |
2246 | } | 2251 | } |
2252 | EXPORT_SYMBOL(db8500_prcmu_load_a9wdog); | ||
2247 | 2253 | ||
2248 | /** | 2254 | /** |
2249 | * prcmu_abb_read() - Read register value(s) from the ABB. | 2255 | * prcmu_abb_read() - Read register value(s) from the ABB. |
@@ -2524,7 +2530,7 @@ static bool read_mailbox_0(void) | |||
2524 | 2530 | ||
2525 | for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) { | 2531 | for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) { |
2526 | if (ev & prcmu_irq_bit[n]) | 2532 | if (ev & prcmu_irq_bit[n]) |
2527 | generic_handle_irq(IRQ_PRCMU_BASE + n); | 2533 | generic_handle_irq(irq_find_mapping(db8500_irq_domain, n)); |
2528 | } | 2534 | } |
2529 | r = true; | 2535 | r = true; |
2530 | break; | 2536 | break; |
@@ -2737,13 +2743,14 @@ static int db8500_irq_map(struct irq_domain *d, unsigned int virq, | |||
2737 | } | 2743 | } |
2738 | 2744 | ||
2739 | static struct irq_domain_ops db8500_irq_ops = { | 2745 | static struct irq_domain_ops db8500_irq_ops = { |
2740 | .map = db8500_irq_map, | 2746 | .map = db8500_irq_map, |
2741 | .xlate = irq_domain_xlate_twocell, | 2747 | .xlate = irq_domain_xlate_twocell, |
2742 | }; | 2748 | }; |
2743 | 2749 | ||
2744 | static int db8500_irq_init(struct device_node *np) | 2750 | static int db8500_irq_init(struct device_node *np) |
2745 | { | 2751 | { |
2746 | int irq_base = -1; | 2752 | int irq_base = 0; |
2753 | int i; | ||
2747 | 2754 | ||
2748 | /* In the device tree case, just take some IRQs */ | 2755 | /* In the device tree case, just take some IRQs */ |
2749 | if (!np) | 2756 | if (!np) |
@@ -2758,6 +2765,10 @@ static int db8500_irq_init(struct device_node *np) | |||
2758 | return -ENOSYS; | 2765 | return -ENOSYS; |
2759 | } | 2766 | } |
2760 | 2767 | ||
2768 | /* All wakeups will be used, so create mappings for all */ | ||
2769 | for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) | ||
2770 | irq_create_mapping(db8500_irq_domain, i); | ||
2771 | |||
2761 | return 0; | 2772 | return 0; |
2762 | } | 2773 | } |
2763 | 2774 | ||
@@ -3064,6 +3075,11 @@ static struct resource ab8500_resources[] = { | |||
3064 | } | 3075 | } |
3065 | }; | 3076 | }; |
3066 | 3077 | ||
3078 | static struct ux500_wdt_data db8500_wdt_pdata = { | ||
3079 | .timeout = 600, /* 10 minutes */ | ||
3080 | .has_28_bits_resolution = true, | ||
3081 | }; | ||
3082 | |||
3067 | static struct mfd_cell db8500_prcmu_devs[] = { | 3083 | static struct mfd_cell db8500_prcmu_devs[] = { |
3068 | { | 3084 | { |
3069 | .name = "db8500-prcmu-regulators", | 3085 | .name = "db8500-prcmu-regulators", |
@@ -3078,6 +3094,12 @@ static struct mfd_cell db8500_prcmu_devs[] = { | |||
3078 | .pdata_size = sizeof(db8500_cpufreq_table), | 3094 | .pdata_size = sizeof(db8500_cpufreq_table), |
3079 | }, | 3095 | }, |
3080 | { | 3096 | { |
3097 | .name = "ux500_wdt", | ||
3098 | .platform_data = &db8500_wdt_pdata, | ||
3099 | .pdata_size = sizeof(db8500_wdt_pdata), | ||
3100 | .id = -1, | ||
3101 | }, | ||
3102 | { | ||
3081 | .name = "ab8500-core", | 3103 | .name = "ab8500-core", |
3082 | .of_compatible = "stericsson,ab8500", | 3104 | .of_compatible = "stericsson,ab8500", |
3083 | .num_resources = ARRAY_SIZE(ab8500_resources), | 3105 | .num_resources = ARRAY_SIZE(ab8500_resources), |
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index d9d930302e98..a0cfdf980748 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -75,8 +75,10 @@ | |||
75 | #define ACPIBASE_GCS_OFF 0x3410 | 75 | #define ACPIBASE_GCS_OFF 0x3410 |
76 | #define ACPIBASE_GCS_END 0x3414 | 76 | #define ACPIBASE_GCS_END 0x3414 |
77 | 77 | ||
78 | #define GPIOBASE 0x48 | 78 | #define GPIOBASE_ICH0 0x58 |
79 | #define GPIOCTRL 0x4C | 79 | #define GPIOCTRL_ICH0 0x5C |
80 | #define GPIOBASE_ICH6 0x48 | ||
81 | #define GPIOCTRL_ICH6 0x4C | ||
80 | 82 | ||
81 | #define RCBABASE 0xf0 | 83 | #define RCBABASE 0xf0 |
82 | 84 | ||
@@ -84,8 +86,17 @@ | |||
84 | #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) | 86 | #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) |
85 | #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) | 87 | #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) |
86 | 88 | ||
87 | static int lpc_ich_acpi_save = -1; | 89 | struct lpc_ich_cfg { |
88 | static int lpc_ich_gpio_save = -1; | 90 | int base; |
91 | int ctrl; | ||
92 | int save; | ||
93 | }; | ||
94 | |||
95 | struct lpc_ich_priv { | ||
96 | int chipset; | ||
97 | struct lpc_ich_cfg acpi; | ||
98 | struct lpc_ich_cfg gpio; | ||
99 | }; | ||
89 | 100 | ||
90 | static struct resource wdt_ich_res[] = { | 101 | static struct resource wdt_ich_res[] = { |
91 | /* ACPI - TCO */ | 102 | /* ACPI - TCO */ |
@@ -661,39 +672,44 @@ MODULE_DEVICE_TABLE(pci, lpc_ich_ids); | |||
661 | 672 | ||
662 | static void lpc_ich_restore_config_space(struct pci_dev *dev) | 673 | static void lpc_ich_restore_config_space(struct pci_dev *dev) |
663 | { | 674 | { |
664 | if (lpc_ich_acpi_save >= 0) { | 675 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
665 | pci_write_config_byte(dev, ACPICTRL, lpc_ich_acpi_save); | 676 | |
666 | lpc_ich_acpi_save = -1; | 677 | if (priv->acpi.save >= 0) { |
678 | pci_write_config_byte(dev, priv->acpi.ctrl, priv->acpi.save); | ||
679 | priv->acpi.save = -1; | ||
667 | } | 680 | } |
668 | 681 | ||
669 | if (lpc_ich_gpio_save >= 0) { | 682 | if (priv->gpio.save >= 0) { |
670 | pci_write_config_byte(dev, GPIOCTRL, lpc_ich_gpio_save); | 683 | pci_write_config_byte(dev, priv->gpio.ctrl, priv->gpio.save); |
671 | lpc_ich_gpio_save = -1; | 684 | priv->gpio.save = -1; |
672 | } | 685 | } |
673 | } | 686 | } |
674 | 687 | ||
675 | static void lpc_ich_enable_acpi_space(struct pci_dev *dev) | 688 | static void lpc_ich_enable_acpi_space(struct pci_dev *dev) |
676 | { | 689 | { |
690 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | ||
677 | u8 reg_save; | 691 | u8 reg_save; |
678 | 692 | ||
679 | pci_read_config_byte(dev, ACPICTRL, ®_save); | 693 | pci_read_config_byte(dev, priv->acpi.ctrl, ®_save); |
680 | pci_write_config_byte(dev, ACPICTRL, reg_save | 0x10); | 694 | pci_write_config_byte(dev, priv->acpi.ctrl, reg_save | 0x10); |
681 | lpc_ich_acpi_save = reg_save; | 695 | priv->acpi.save = reg_save; |
682 | } | 696 | } |
683 | 697 | ||
684 | static void lpc_ich_enable_gpio_space(struct pci_dev *dev) | 698 | static void lpc_ich_enable_gpio_space(struct pci_dev *dev) |
685 | { | 699 | { |
700 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | ||
686 | u8 reg_save; | 701 | u8 reg_save; |
687 | 702 | ||
688 | pci_read_config_byte(dev, GPIOCTRL, ®_save); | 703 | pci_read_config_byte(dev, priv->gpio.ctrl, ®_save); |
689 | pci_write_config_byte(dev, GPIOCTRL, reg_save | 0x10); | 704 | pci_write_config_byte(dev, priv->gpio.ctrl, reg_save | 0x10); |
690 | lpc_ich_gpio_save = reg_save; | 705 | priv->gpio.save = reg_save; |
691 | } | 706 | } |
692 | 707 | ||
693 | static void lpc_ich_finalize_cell(struct mfd_cell *cell, | 708 | static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) |
694 | const struct pci_device_id *id) | ||
695 | { | 709 | { |
696 | cell->platform_data = &lpc_chipset_info[id->driver_data]; | 710 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
711 | |||
712 | cell->platform_data = &lpc_chipset_info[priv->chipset]; | ||
697 | cell->pdata_size = sizeof(struct lpc_ich_info); | 713 | cell->pdata_size = sizeof(struct lpc_ich_info); |
698 | } | 714 | } |
699 | 715 | ||
@@ -721,9 +737,9 @@ static int lpc_ich_check_conflict_gpio(struct resource *res) | |||
721 | return use_gpio ? use_gpio : ret; | 737 | return use_gpio ? use_gpio : ret; |
722 | } | 738 | } |
723 | 739 | ||
724 | static int lpc_ich_init_gpio(struct pci_dev *dev, | 740 | static int lpc_ich_init_gpio(struct pci_dev *dev) |
725 | const struct pci_device_id *id) | ||
726 | { | 741 | { |
742 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | ||
727 | u32 base_addr_cfg; | 743 | u32 base_addr_cfg; |
728 | u32 base_addr; | 744 | u32 base_addr; |
729 | int ret; | 745 | int ret; |
@@ -731,7 +747,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev, | |||
731 | struct resource *res; | 747 | struct resource *res; |
732 | 748 | ||
733 | /* Setup power management base register */ | 749 | /* Setup power management base register */ |
734 | pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg); | 750 | pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg); |
735 | base_addr = base_addr_cfg & 0x0000ff80; | 751 | base_addr = base_addr_cfg & 0x0000ff80; |
736 | if (!base_addr) { | 752 | if (!base_addr) { |
737 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); | 753 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); |
@@ -757,7 +773,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev, | |||
757 | 773 | ||
758 | gpe0_done: | 774 | gpe0_done: |
759 | /* Setup GPIO base register */ | 775 | /* Setup GPIO base register */ |
760 | pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); | 776 | pci_read_config_dword(dev, priv->gpio.base, &base_addr_cfg); |
761 | base_addr = base_addr_cfg & 0x0000ff80; | 777 | base_addr = base_addr_cfg & 0x0000ff80; |
762 | if (!base_addr) { | 778 | if (!base_addr) { |
763 | dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); | 779 | dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); |
@@ -768,7 +784,7 @@ gpe0_done: | |||
768 | /* Older devices provide fewer GPIO and have a smaller resource size. */ | 784 | /* Older devices provide fewer GPIO and have a smaller resource size. */ |
769 | res = &gpio_ich_res[ICH_RES_GPIO]; | 785 | res = &gpio_ich_res[ICH_RES_GPIO]; |
770 | res->start = base_addr; | 786 | res->start = base_addr; |
771 | switch (lpc_chipset_info[id->driver_data].gpio_version) { | 787 | switch (lpc_chipset_info[priv->chipset].gpio_version) { |
772 | case ICH_V5_GPIO: | 788 | case ICH_V5_GPIO: |
773 | case ICH_V10CORP_GPIO: | 789 | case ICH_V10CORP_GPIO: |
774 | res->end = res->start + 128 - 1; | 790 | res->end = res->start + 128 - 1; |
@@ -784,10 +800,10 @@ gpe0_done: | |||
784 | acpi_conflict = true; | 800 | acpi_conflict = true; |
785 | goto gpio_done; | 801 | goto gpio_done; |
786 | } | 802 | } |
787 | lpc_chipset_info[id->driver_data].use_gpio = ret; | 803 | lpc_chipset_info[priv->chipset].use_gpio = ret; |
788 | lpc_ich_enable_gpio_space(dev); | 804 | lpc_ich_enable_gpio_space(dev); |
789 | 805 | ||
790 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); | 806 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_GPIO]); |
791 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], | 807 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], |
792 | 1, NULL, 0, NULL); | 808 | 1, NULL, 0, NULL); |
793 | 809 | ||
@@ -798,16 +814,16 @@ gpio_done: | |||
798 | return ret; | 814 | return ret; |
799 | } | 815 | } |
800 | 816 | ||
801 | static int lpc_ich_init_wdt(struct pci_dev *dev, | 817 | static int lpc_ich_init_wdt(struct pci_dev *dev) |
802 | const struct pci_device_id *id) | ||
803 | { | 818 | { |
819 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | ||
804 | u32 base_addr_cfg; | 820 | u32 base_addr_cfg; |
805 | u32 base_addr; | 821 | u32 base_addr; |
806 | int ret; | 822 | int ret; |
807 | struct resource *res; | 823 | struct resource *res; |
808 | 824 | ||
809 | /* Setup power management base register */ | 825 | /* Setup power management base register */ |
810 | pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg); | 826 | pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg); |
811 | base_addr = base_addr_cfg & 0x0000ff80; | 827 | base_addr = base_addr_cfg & 0x0000ff80; |
812 | if (!base_addr) { | 828 | if (!base_addr) { |
813 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); | 829 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); |
@@ -830,7 +846,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev, | |||
830 | * we have to read RCBA from PCI Config space 0xf0 and use | 846 | * we have to read RCBA from PCI Config space 0xf0 and use |
831 | * it as base. GCS = RCBA + ICH6_GCS(0x3410). | 847 | * it as base. GCS = RCBA + ICH6_GCS(0x3410). |
832 | */ | 848 | */ |
833 | if (lpc_chipset_info[id->driver_data].iTCO_version == 1) { | 849 | if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { |
834 | /* Don't register iomem for TCO ver 1 */ | 850 | /* Don't register iomem for TCO ver 1 */ |
835 | lpc_ich_cells[LPC_WDT].num_resources--; | 851 | lpc_ich_cells[LPC_WDT].num_resources--; |
836 | } else { | 852 | } else { |
@@ -847,7 +863,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev, | |||
847 | res->end = base_addr + ACPIBASE_GCS_END; | 863 | res->end = base_addr + ACPIBASE_GCS_END; |
848 | } | 864 | } |
849 | 865 | ||
850 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); | 866 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); |
851 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], | 867 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], |
852 | 1, NULL, 0, NULL); | 868 | 1, NULL, 0, NULL); |
853 | 869 | ||
@@ -858,14 +874,35 @@ wdt_done: | |||
858 | static int lpc_ich_probe(struct pci_dev *dev, | 874 | static int lpc_ich_probe(struct pci_dev *dev, |
859 | const struct pci_device_id *id) | 875 | const struct pci_device_id *id) |
860 | { | 876 | { |
877 | struct lpc_ich_priv *priv; | ||
861 | int ret; | 878 | int ret; |
862 | bool cell_added = false; | 879 | bool cell_added = false; |
863 | 880 | ||
864 | ret = lpc_ich_init_wdt(dev, id); | 881 | priv = kmalloc(GFP_KERNEL, sizeof(struct lpc_ich_priv)); |
882 | if (!priv) | ||
883 | return -ENOMEM; | ||
884 | |||
885 | priv->chipset = id->driver_data; | ||
886 | priv->acpi.save = -1; | ||
887 | priv->acpi.base = ACPIBASE; | ||
888 | priv->acpi.ctrl = ACPICTRL; | ||
889 | |||
890 | priv->gpio.save = -1; | ||
891 | if (priv->chipset <= LPC_ICH5) { | ||
892 | priv->gpio.base = GPIOBASE_ICH0; | ||
893 | priv->gpio.ctrl = GPIOCTRL_ICH0; | ||
894 | } else { | ||
895 | priv->gpio.base = GPIOBASE_ICH6; | ||
896 | priv->gpio.ctrl = GPIOCTRL_ICH6; | ||
897 | } | ||
898 | |||
899 | pci_set_drvdata(dev, priv); | ||
900 | |||
901 | ret = lpc_ich_init_wdt(dev); | ||
865 | if (!ret) | 902 | if (!ret) |
866 | cell_added = true; | 903 | cell_added = true; |
867 | 904 | ||
868 | ret = lpc_ich_init_gpio(dev, id); | 905 | ret = lpc_ich_init_gpio(dev); |
869 | if (!ret) | 906 | if (!ret) |
870 | cell_added = true; | 907 | cell_added = true; |
871 | 908 | ||
@@ -876,6 +913,8 @@ static int lpc_ich_probe(struct pci_dev *dev, | |||
876 | if (!cell_added) { | 913 | if (!cell_added) { |
877 | dev_warn(&dev->dev, "No MFD cells added\n"); | 914 | dev_warn(&dev->dev, "No MFD cells added\n"); |
878 | lpc_ich_restore_config_space(dev); | 915 | lpc_ich_restore_config_space(dev); |
916 | pci_set_drvdata(dev, NULL); | ||
917 | kfree(priv); | ||
879 | return -ENODEV; | 918 | return -ENODEV; |
880 | } | 919 | } |
881 | 920 | ||
@@ -884,8 +923,12 @@ static int lpc_ich_probe(struct pci_dev *dev, | |||
884 | 923 | ||
885 | static void lpc_ich_remove(struct pci_dev *dev) | 924 | static void lpc_ich_remove(struct pci_dev *dev) |
886 | { | 925 | { |
926 | void *priv = pci_get_drvdata(dev); | ||
927 | |||
887 | mfd_remove_devices(&dev->dev); | 928 | mfd_remove_devices(&dev->dev); |
888 | lpc_ich_restore_config_space(dev); | 929 | lpc_ich_restore_config_space(dev); |
930 | pci_set_drvdata(dev, NULL); | ||
931 | kfree(priv); | ||
889 | } | 932 | } |
890 | 933 | ||
891 | static struct pci_driver lpc_ich_driver = { | 934 | static struct pci_driver lpc_ich_driver = { |
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index f6878f8db57d..4d73963cd8f0 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -93,15 +93,6 @@ static int max77686_i2c_probe(struct i2c_client *i2c, | |||
93 | if (max77686 == NULL) | 93 | if (max77686 == NULL) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | 95 | ||
96 | max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config); | ||
97 | if (IS_ERR(max77686->regmap)) { | ||
98 | ret = PTR_ERR(max77686->regmap); | ||
99 | dev_err(max77686->dev, "Failed to allocate register map: %d\n", | ||
100 | ret); | ||
101 | kfree(max77686); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | i2c_set_clientdata(i2c, max77686); | 96 | i2c_set_clientdata(i2c, max77686); |
106 | max77686->dev = &i2c->dev; | 97 | max77686->dev = &i2c->dev; |
107 | max77686->i2c = i2c; | 98 | max77686->i2c = i2c; |
@@ -111,6 +102,15 @@ static int max77686_i2c_probe(struct i2c_client *i2c, | |||
111 | max77686->irq_gpio = pdata->irq_gpio; | 102 | max77686->irq_gpio = pdata->irq_gpio; |
112 | max77686->irq = i2c->irq; | 103 | max77686->irq = i2c->irq; |
113 | 104 | ||
105 | max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config); | ||
106 | if (IS_ERR(max77686->regmap)) { | ||
107 | ret = PTR_ERR(max77686->regmap); | ||
108 | dev_err(max77686->dev, "Failed to allocate register map: %d\n", | ||
109 | ret); | ||
110 | kfree(max77686); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | if (regmap_read(max77686->regmap, | 114 | if (regmap_read(max77686->regmap, |
115 | MAX77686_REG_DEVICE_ID, &data) < 0) { | 115 | MAX77686_REG_DEVICE_ID, &data) < 0) { |
116 | dev_err(max77686->dev, | 116 | dev_err(max77686->dev, |
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index cc5155e20494..9e60fed5ff82 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -114,35 +114,37 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
114 | u8 reg_data; | 114 | u8 reg_data; |
115 | int ret = 0; | 115 | int ret = 0; |
116 | 116 | ||
117 | if (!pdata) { | ||
118 | dev_err(&i2c->dev, "No platform data found.\n"); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | |||
117 | max77693 = devm_kzalloc(&i2c->dev, | 122 | max77693 = devm_kzalloc(&i2c->dev, |
118 | sizeof(struct max77693_dev), GFP_KERNEL); | 123 | sizeof(struct max77693_dev), GFP_KERNEL); |
119 | if (max77693 == NULL) | 124 | if (max77693 == NULL) |
120 | return -ENOMEM; | 125 | return -ENOMEM; |
121 | 126 | ||
122 | max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); | ||
123 | if (IS_ERR(max77693->regmap)) { | ||
124 | ret = PTR_ERR(max77693->regmap); | ||
125 | dev_err(max77693->dev,"failed to allocate register map: %d\n", | ||
126 | ret); | ||
127 | goto err_regmap; | ||
128 | } | ||
129 | |||
130 | i2c_set_clientdata(i2c, max77693); | 127 | i2c_set_clientdata(i2c, max77693); |
131 | max77693->dev = &i2c->dev; | 128 | max77693->dev = &i2c->dev; |
132 | max77693->i2c = i2c; | 129 | max77693->i2c = i2c; |
133 | max77693->irq = i2c->irq; | 130 | max77693->irq = i2c->irq; |
134 | max77693->type = id->driver_data; | 131 | max77693->type = id->driver_data; |
135 | 132 | ||
136 | if (!pdata) | 133 | max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); |
137 | goto err_regmap; | 134 | if (IS_ERR(max77693->regmap)) { |
135 | ret = PTR_ERR(max77693->regmap); | ||
136 | dev_err(max77693->dev, "failed to allocate register map: %d\n", | ||
137 | ret); | ||
138 | return ret; | ||
139 | } | ||
138 | 140 | ||
139 | max77693->wakeup = pdata->wakeup; | 141 | max77693->wakeup = pdata->wakeup; |
140 | 142 | ||
141 | if (max77693_read_reg(max77693->regmap, | 143 | ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, |
142 | MAX77693_PMIC_REG_PMIC_ID2, ®_data) < 0) { | 144 | ®_data); |
145 | if (ret < 0) { | ||
143 | dev_err(max77693->dev, "device not found on this channel\n"); | 146 | dev_err(max77693->dev, "device not found on this channel\n"); |
144 | ret = -ENODEV; | 147 | return ret; |
145 | goto err_regmap; | ||
146 | } else | 148 | } else |
147 | dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); | 149 | dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); |
148 | 150 | ||
@@ -163,7 +165,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
163 | ret = PTR_ERR(max77693->regmap_muic); | 165 | ret = PTR_ERR(max77693->regmap_muic); |
164 | dev_err(max77693->dev, | 166 | dev_err(max77693->dev, |
165 | "failed to allocate register map: %d\n", ret); | 167 | "failed to allocate register map: %d\n", ret); |
166 | goto err_regmap; | 168 | goto err_regmap_muic; |
167 | } | 169 | } |
168 | 170 | ||
169 | ret = max77693_irq_init(max77693); | 171 | ret = max77693_irq_init(max77693); |
@@ -184,9 +186,9 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
184 | err_mfd: | 186 | err_mfd: |
185 | max77693_irq_exit(max77693); | 187 | max77693_irq_exit(max77693); |
186 | err_irq: | 188 | err_irq: |
189 | err_regmap_muic: | ||
187 | i2c_unregister_device(max77693->muic); | 190 | i2c_unregister_device(max77693->muic); |
188 | i2c_unregister_device(max77693->haptic); | 191 | i2c_unregister_device(max77693->haptic); |
189 | err_regmap: | ||
190 | return ret; | 192 | return ret; |
191 | } | 193 | } |
192 | 194 | ||
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index e32466e865b9..f0cc40296d8c 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -14,10 +14,13 @@ | |||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/irqdomain.h> | ||
17 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
18 | #include <linux/regulator/machine.h> | 19 | #include <linux/regulator/machine.h> |
19 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
20 | #include <linux/mfd/max8925.h> | 21 | #include <linux/mfd/max8925.h> |
22 | #include <linux/of.h> | ||
23 | #include <linux/of_platform.h> | ||
21 | 24 | ||
22 | static struct resource bk_resources[] = { | 25 | static struct resource bk_resources[] = { |
23 | { 0x84, 0x84, "mode control", IORESOURCE_REG, }, | 26 | { 0x84, 0x84, "mode control", IORESOURCE_REG, }, |
@@ -639,17 +642,33 @@ static struct irq_chip max8925_irq_chip = { | |||
639 | .irq_disable = max8925_irq_disable, | 642 | .irq_disable = max8925_irq_disable, |
640 | }; | 643 | }; |
641 | 644 | ||
645 | static int max8925_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
646 | irq_hw_number_t hw) | ||
647 | { | ||
648 | irq_set_chip_data(virq, d->host_data); | ||
649 | irq_set_chip_and_handler(virq, &max8925_irq_chip, handle_edge_irq); | ||
650 | irq_set_nested_thread(virq, 1); | ||
651 | #ifdef CONFIG_ARM | ||
652 | set_irq_flags(virq, IRQF_VALID); | ||
653 | #else | ||
654 | irq_set_noprobe(virq); | ||
655 | #endif | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | static struct irq_domain_ops max8925_irq_domain_ops = { | ||
660 | .map = max8925_irq_domain_map, | ||
661 | .xlate = irq_domain_xlate_onetwocell, | ||
662 | }; | ||
663 | |||
664 | |||
642 | static int max8925_irq_init(struct max8925_chip *chip, int irq, | 665 | static int max8925_irq_init(struct max8925_chip *chip, int irq, |
643 | struct max8925_platform_data *pdata) | 666 | struct max8925_platform_data *pdata) |
644 | { | 667 | { |
645 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; | 668 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; |
646 | int i, ret; | 669 | int ret; |
647 | int __irq; | 670 | struct device_node *node = chip->dev->of_node; |
648 | 671 | ||
649 | if (!pdata || !pdata->irq_base) { | ||
650 | dev_warn(chip->dev, "No interrupt support on IRQ base\n"); | ||
651 | return -EINVAL; | ||
652 | } | ||
653 | /* clear all interrupts */ | 672 | /* clear all interrupts */ |
654 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); | 673 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); |
655 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); | 674 | max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); |
@@ -667,35 +686,30 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, | |||
667 | max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); | 686 | max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); |
668 | 687 | ||
669 | mutex_init(&chip->irq_lock); | 688 | mutex_init(&chip->irq_lock); |
670 | chip->core_irq = irq; | 689 | chip->irq_base = irq_alloc_descs(-1, 0, MAX8925_NR_IRQS, 0); |
671 | chip->irq_base = pdata->irq_base; | 690 | if (chip->irq_base < 0) { |
672 | 691 | dev_err(chip->dev, "Failed to allocate interrupts, ret:%d\n", | |
673 | /* register with genirq */ | 692 | chip->irq_base); |
674 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { | 693 | return -EBUSY; |
675 | __irq = i + chip->irq_base; | ||
676 | irq_set_chip_data(__irq, chip); | ||
677 | irq_set_chip_and_handler(__irq, &max8925_irq_chip, | ||
678 | handle_edge_irq); | ||
679 | irq_set_nested_thread(__irq, 1); | ||
680 | #ifdef CONFIG_ARM | ||
681 | set_irq_flags(__irq, IRQF_VALID); | ||
682 | #else | ||
683 | irq_set_noprobe(__irq); | ||
684 | #endif | ||
685 | } | ||
686 | if (!irq) { | ||
687 | dev_warn(chip->dev, "No interrupt support on core IRQ\n"); | ||
688 | goto tsc_irq; | ||
689 | } | 694 | } |
690 | 695 | ||
696 | irq_domain_add_legacy(node, MAX8925_NR_IRQS, chip->irq_base, 0, | ||
697 | &max8925_irq_domain_ops, chip); | ||
698 | |||
699 | /* request irq handler for pmic main irq*/ | ||
700 | chip->core_irq = irq; | ||
701 | if (!chip->core_irq) | ||
702 | return -EBUSY; | ||
691 | ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT, | 703 | ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT, |
692 | "max8925", chip); | 704 | "max8925", chip); |
693 | if (ret) { | 705 | if (ret) { |
694 | dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); | 706 | dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); |
695 | chip->core_irq = 0; | 707 | chip->core_irq = 0; |
708 | return -EBUSY; | ||
696 | } | 709 | } |
697 | 710 | ||
698 | tsc_irq: | 711 | /* request irq handler for pmic tsc irq*/ |
712 | |||
699 | /* mask TSC interrupt */ | 713 | /* mask TSC interrupt */ |
700 | max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); | 714 | max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); |
701 | 715 | ||
@@ -704,7 +718,6 @@ tsc_irq: | |||
704 | return 0; | 718 | return 0; |
705 | } | 719 | } |
706 | chip->tsc_irq = pdata->tsc_irq; | 720 | chip->tsc_irq = pdata->tsc_irq; |
707 | |||
708 | ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, | 721 | ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, |
709 | flags | IRQF_ONESHOT, "max8925-tsc", chip); | 722 | flags | IRQF_ONESHOT, "max8925-tsc", chip); |
710 | if (ret) { | 723 | if (ret) { |
@@ -846,7 +859,7 @@ int max8925_device_init(struct max8925_chip *chip, | |||
846 | 859 | ||
847 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 860 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
848 | ARRAY_SIZE(rtc_devs), | 861 | ARRAY_SIZE(rtc_devs), |
849 | &rtc_resources[0], chip->irq_base, NULL); | 862 | NULL, chip->irq_base, NULL); |
850 | if (ret < 0) { | 863 | if (ret < 0) { |
851 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 864 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
852 | goto out; | 865 | goto out; |
@@ -854,7 +867,7 @@ int max8925_device_init(struct max8925_chip *chip, | |||
854 | 867 | ||
855 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 868 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
856 | ARRAY_SIZE(onkey_devs), | 869 | ARRAY_SIZE(onkey_devs), |
857 | &onkey_resources[0], 0, NULL); | 870 | NULL, chip->irq_base, NULL); |
858 | if (ret < 0) { | 871 | if (ret < 0) { |
859 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 872 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
860 | goto out_dev; | 873 | goto out_dev; |
@@ -873,21 +886,19 @@ int max8925_device_init(struct max8925_chip *chip, | |||
873 | goto out_dev; | 886 | goto out_dev; |
874 | } | 887 | } |
875 | 888 | ||
876 | if (pdata && pdata->power) { | 889 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], |
877 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], | 890 | ARRAY_SIZE(power_devs), |
878 | ARRAY_SIZE(power_devs), | 891 | NULL, 0, NULL); |
879 | &power_supply_resources[0], 0, NULL); | 892 | if (ret < 0) { |
880 | if (ret < 0) { | 893 | dev_err(chip->dev, |
881 | dev_err(chip->dev, "Failed to add power supply " | 894 | "Failed to add power supply subdev, err = %d\n", ret); |
882 | "subdev\n"); | 895 | goto out_dev; |
883 | goto out_dev; | ||
884 | } | ||
885 | } | 896 | } |
886 | 897 | ||
887 | if (pdata && pdata->touch) { | 898 | if (pdata && pdata->touch) { |
888 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 899 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
889 | ARRAY_SIZE(touch_devs), | 900 | ARRAY_SIZE(touch_devs), |
890 | &touch_resources[0], 0, NULL); | 901 | NULL, chip->tsc_irq, NULL); |
891 | if (ret < 0) { | 902 | if (ret < 0) { |
892 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 903 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
893 | goto out_dev; | 904 | goto out_dev; |
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 00b5b456063d..92bbebd31598 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c | |||
@@ -135,13 +135,37 @@ static const struct i2c_device_id max8925_id_table[] = { | |||
135 | }; | 135 | }; |
136 | MODULE_DEVICE_TABLE(i2c, max8925_id_table); | 136 | MODULE_DEVICE_TABLE(i2c, max8925_id_table); |
137 | 137 | ||
138 | static int max8925_dt_init(struct device_node *np, struct device *dev, | ||
139 | struct max8925_platform_data *pdata) | ||
140 | { | ||
141 | int ret; | ||
142 | |||
143 | ret = of_property_read_u32(np, "maxim,tsc-irq", &pdata->tsc_irq); | ||
144 | if (ret) { | ||
145 | dev_err(dev, "Not found maxim,tsc-irq property\n"); | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | return 0; | ||
149 | } | ||
150 | |||
138 | static int max8925_probe(struct i2c_client *client, | 151 | static int max8925_probe(struct i2c_client *client, |
139 | const struct i2c_device_id *id) | 152 | const struct i2c_device_id *id) |
140 | { | 153 | { |
141 | struct max8925_platform_data *pdata = client->dev.platform_data; | 154 | struct max8925_platform_data *pdata = client->dev.platform_data; |
142 | static struct max8925_chip *chip; | 155 | static struct max8925_chip *chip; |
143 | 156 | struct device_node *node = client->dev.of_node; | |
144 | if (!pdata) { | 157 | |
158 | if (node && !pdata) { | ||
159 | /* parse DT to get platform data */ | ||
160 | pdata = devm_kzalloc(&client->dev, | ||
161 | sizeof(struct max8925_platform_data), | ||
162 | GFP_KERNEL); | ||
163 | if (!pdata) | ||
164 | return -ENOMEM; | ||
165 | |||
166 | if (max8925_dt_init(node, &client->dev, pdata)) | ||
167 | return -EINVAL; | ||
168 | } else if (!pdata) { | ||
145 | pr_info("%s: platform data is missing\n", __func__); | 169 | pr_info("%s: platform data is missing\n", __func__); |
146 | return -EINVAL; | 170 | return -EINVAL; |
147 | } | 171 | } |
@@ -203,11 +227,18 @@ static int max8925_resume(struct device *dev) | |||
203 | 227 | ||
204 | static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume); | 228 | static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume); |
205 | 229 | ||
230 | static const struct of_device_id max8925_dt_ids[] = { | ||
231 | { .compatible = "maxim,max8925", }, | ||
232 | {}, | ||
233 | }; | ||
234 | MODULE_DEVICE_TABLE(of, max8925_dt_ids); | ||
235 | |||
206 | static struct i2c_driver max8925_driver = { | 236 | static struct i2c_driver max8925_driver = { |
207 | .driver = { | 237 | .driver = { |
208 | .name = "max8925", | 238 | .name = "max8925", |
209 | .owner = THIS_MODULE, | 239 | .owner = THIS_MODULE, |
210 | .pm = &max8925_pm_ops, | 240 | .pm = &max8925_pm_ops, |
241 | .of_match_table = of_match_ptr(max8925_dt_ids), | ||
211 | }, | 242 | }, |
212 | .probe = max8925_probe, | 243 | .probe = max8925_probe, |
213 | .remove = max8925_remove, | 244 | .remove = max8925_remove, |
@@ -217,7 +248,6 @@ static struct i2c_driver max8925_driver = { | |||
217 | static int __init max8925_i2c_init(void) | 248 | static int __init max8925_i2c_init(void) |
218 | { | 249 | { |
219 | int ret; | 250 | int ret; |
220 | |||
221 | ret = i2c_add_driver(&max8925_driver); | 251 | ret = i2c_add_driver(&max8925_driver); |
222 | if (ret != 0) | 252 | if (ret != 0) |
223 | pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); | 253 | pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); |
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 6ffd7a2affdc..bbdbc50a3cca 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c | |||
@@ -39,6 +39,14 @@ enum palmas_ids { | |||
39 | PALMAS_USB_ID, | 39 | PALMAS_USB_ID, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct resource palmas_rtc_resources[] = { | ||
43 | { | ||
44 | .start = PALMAS_RTC_ALARM_IRQ, | ||
45 | .end = PALMAS_RTC_ALARM_IRQ, | ||
46 | .flags = IORESOURCE_IRQ, | ||
47 | }, | ||
48 | }; | ||
49 | |||
42 | static const struct mfd_cell palmas_children[] = { | 50 | static const struct mfd_cell palmas_children[] = { |
43 | { | 51 | { |
44 | .name = "palmas-pmic", | 52 | .name = "palmas-pmic", |
@@ -59,6 +67,8 @@ static const struct mfd_cell palmas_children[] = { | |||
59 | { | 67 | { |
60 | .name = "palmas-rtc", | 68 | .name = "palmas-rtc", |
61 | .id = PALMAS_RTC_ID, | 69 | .id = PALMAS_RTC_ID, |
70 | .resources = &palmas_rtc_resources[0], | ||
71 | .num_resources = ARRAY_SIZE(palmas_rtc_resources), | ||
62 | }, | 72 | }, |
63 | { | 73 | { |
64 | .name = "palmas-pwrbutton", | 74 | .name = "palmas-pwrbutton", |
@@ -456,8 +466,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c, | |||
456 | 466 | ||
457 | ret = mfd_add_devices(palmas->dev, -1, | 467 | ret = mfd_add_devices(palmas->dev, -1, |
458 | children, ARRAY_SIZE(palmas_children), | 468 | children, ARRAY_SIZE(palmas_children), |
459 | NULL, regmap_irq_chip_get_base(palmas->irq_data), | 469 | NULL, 0, |
460 | NULL); | 470 | regmap_irq_get_domain(palmas->irq_data)); |
461 | kfree(children); | 471 | kfree(children); |
462 | 472 | ||
463 | if (ret < 0) | 473 | if (ret < 0) |
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 64803f13bcec..d11567307fbe 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c | |||
@@ -208,6 +208,8 @@ static int pcf50633_probe(struct i2c_client *client, | |||
208 | if (!pcf) | 208 | if (!pcf) |
209 | return -ENOMEM; | 209 | return -ENOMEM; |
210 | 210 | ||
211 | i2c_set_clientdata(client, pcf); | ||
212 | pcf->dev = &client->dev; | ||
211 | pcf->pdata = pdata; | 213 | pcf->pdata = pdata; |
212 | 214 | ||
213 | mutex_init(&pcf->lock); | 215 | mutex_init(&pcf->lock); |
@@ -219,9 +221,6 @@ static int pcf50633_probe(struct i2c_client *client, | |||
219 | return ret; | 221 | return ret; |
220 | } | 222 | } |
221 | 223 | ||
222 | i2c_set_clientdata(client, pcf); | ||
223 | pcf->dev = &client->dev; | ||
224 | |||
225 | version = pcf50633_reg_read(pcf, 0); | 224 | version = pcf50633_reg_read(pcf, 0); |
226 | variant = pcf50633_reg_read(pcf, 1); | 225 | variant = pcf50633_reg_read(pcf, 1); |
227 | if (version < 0 || variant < 0) { | 226 | if (version < 0 || variant < 0) { |
diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c index 89f046ca9e41..2a2d31687b72 100644 --- a/drivers/mfd/rtl8411.c +++ b/drivers/mfd/rtl8411.c | |||
@@ -112,6 +112,31 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card) | |||
112 | BPP_LDO_POWB, BPP_LDO_SUSPEND); | 112 | BPP_LDO_POWB, BPP_LDO_SUSPEND); |
113 | } | 113 | } |
114 | 114 | ||
115 | static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | ||
116 | { | ||
117 | u8 mask, val; | ||
118 | int err; | ||
119 | |||
120 | mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK; | ||
121 | if (voltage == OUTPUT_3V3) { | ||
122 | err = rtsx_pci_write_register(pcr, | ||
123 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); | ||
124 | if (err < 0) | ||
125 | return err; | ||
126 | val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3; | ||
127 | } else if (voltage == OUTPUT_1V8) { | ||
128 | err = rtsx_pci_write_register(pcr, | ||
129 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); | ||
130 | if (err < 0) | ||
131 | return err; | ||
132 | val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8; | ||
133 | } else { | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | return rtsx_pci_write_register(pcr, LDO_CTL, mask, val); | ||
138 | } | ||
139 | |||
115 | static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr) | 140 | static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr) |
116 | { | 141 | { |
117 | unsigned int card_exist; | 142 | unsigned int card_exist; |
@@ -163,6 +188,18 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr) | |||
163 | return card_exist; | 188 | return card_exist; |
164 | } | 189 | } |
165 | 190 | ||
191 | static int rtl8411_conv_clk_and_div_n(int input, int dir) | ||
192 | { | ||
193 | int output; | ||
194 | |||
195 | if (dir == CLK_TO_DIV_N) | ||
196 | output = input * 4 / 5 - 2; | ||
197 | else | ||
198 | output = (input + 2) * 5 / 4; | ||
199 | |||
200 | return output; | ||
201 | } | ||
202 | |||
166 | static const struct pcr_ops rtl8411_pcr_ops = { | 203 | static const struct pcr_ops rtl8411_pcr_ops = { |
167 | .extra_init_hw = rtl8411_extra_init_hw, | 204 | .extra_init_hw = rtl8411_extra_init_hw, |
168 | .optimize_phy = NULL, | 205 | .optimize_phy = NULL, |
@@ -172,7 +209,9 @@ static const struct pcr_ops rtl8411_pcr_ops = { | |||
172 | .disable_auto_blink = rtl8411_disable_auto_blink, | 209 | .disable_auto_blink = rtl8411_disable_auto_blink, |
173 | .card_power_on = rtl8411_card_power_on, | 210 | .card_power_on = rtl8411_card_power_on, |
174 | .card_power_off = rtl8411_card_power_off, | 211 | .card_power_off = rtl8411_card_power_off, |
212 | .switch_output_voltage = rtl8411_switch_output_voltage, | ||
175 | .cd_deglitch = rtl8411_cd_deglitch, | 213 | .cd_deglitch = rtl8411_cd_deglitch, |
214 | .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n, | ||
176 | }; | 215 | }; |
177 | 216 | ||
178 | /* SD Pull Control Enable: | 217 | /* SD Pull Control Enable: |
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c index 283a4f148084..ec78d9fb0879 100644 --- a/drivers/mfd/rts5209.c +++ b/drivers/mfd/rts5209.c | |||
@@ -144,6 +144,33 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card) | |||
144 | return rtsx_pci_send_cmd(pcr, 100); | 144 | return rtsx_pci_send_cmd(pcr, 100); |
145 | } | 145 | } |
146 | 146 | ||
147 | static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | ||
148 | { | ||
149 | int err; | ||
150 | |||
151 | if (voltage == OUTPUT_3V3) { | ||
152 | err = rtsx_pci_write_register(pcr, | ||
153 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); | ||
154 | if (err < 0) | ||
155 | return err; | ||
156 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | ||
157 | if (err < 0) | ||
158 | return err; | ||
159 | } else if (voltage == OUTPUT_1V8) { | ||
160 | err = rtsx_pci_write_register(pcr, | ||
161 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); | ||
162 | if (err < 0) | ||
163 | return err; | ||
164 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); | ||
165 | if (err < 0) | ||
166 | return err; | ||
167 | } else { | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
147 | static const struct pcr_ops rts5209_pcr_ops = { | 174 | static const struct pcr_ops rts5209_pcr_ops = { |
148 | .extra_init_hw = rts5209_extra_init_hw, | 175 | .extra_init_hw = rts5209_extra_init_hw, |
149 | .optimize_phy = rts5209_optimize_phy, | 176 | .optimize_phy = rts5209_optimize_phy, |
@@ -153,7 +180,9 @@ static const struct pcr_ops rts5209_pcr_ops = { | |||
153 | .disable_auto_blink = rts5209_disable_auto_blink, | 180 | .disable_auto_blink = rts5209_disable_auto_blink, |
154 | .card_power_on = rts5209_card_power_on, | 181 | .card_power_on = rts5209_card_power_on, |
155 | .card_power_off = rts5209_card_power_off, | 182 | .card_power_off = rts5209_card_power_off, |
183 | .switch_output_voltage = rts5209_switch_output_voltage, | ||
156 | .cd_deglitch = NULL, | 184 | .cd_deglitch = NULL, |
185 | .conv_clk_and_div_n = NULL, | ||
157 | }; | 186 | }; |
158 | 187 | ||
159 | /* SD Pull Control Enable: | 188 | /* SD Pull Control Enable: |
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c new file mode 100644 index 000000000000..fc831dcb1480 --- /dev/null +++ b/drivers/mfd/rts5227.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* Driver for Realtek PCI-Express card reader | ||
2 | * | ||
3 | * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2, or (at your option) any | ||
8 | * later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, see <http://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * Author: | ||
19 | * Wei WANG <wei_wang@realsil.com.cn> | ||
20 | * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China | ||
21 | * | ||
22 | * Roger Tseng <rogerable@realtek.com> | ||
23 | * No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/mfd/rtsx_pci.h> | ||
29 | |||
30 | #include "rtsx_pcr.h" | ||
31 | |||
32 | static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) | ||
33 | { | ||
34 | u16 cap; | ||
35 | |||
36 | rtsx_pci_init_cmd(pcr); | ||
37 | |||
38 | /* Configure GPIO as output */ | ||
39 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02); | ||
40 | /* Switch LDO3318 source from DV33 to card_3v3 */ | ||
41 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00); | ||
42 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01); | ||
43 | /* LED shine disabled, set initial shine cycle period */ | ||
44 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); | ||
45 | /* Configure LTR */ | ||
46 | pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cap); | ||
47 | if (cap & PCI_EXP_LTR_EN) | ||
48 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3); | ||
49 | /* Configure OBFF */ | ||
50 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03); | ||
51 | /* Configure force_clock_req | ||
52 | * Maybe We should define 0xFF03 as some name | ||
53 | */ | ||
54 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08); | ||
55 | /* Correct driving */ | ||
56 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
57 | SD30_CLK_DRIVE_SEL, 0xFF, 0x96); | ||
58 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
59 | SD30_CMD_DRIVE_SEL, 0xFF, 0x96); | ||
60 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
61 | SD30_DAT_DRIVE_SEL, 0xFF, 0x96); | ||
62 | |||
63 | return rtsx_pci_send_cmd(pcr, 100); | ||
64 | } | ||
65 | |||
66 | static int rts5227_optimize_phy(struct rtsx_pcr *pcr) | ||
67 | { | ||
68 | /* Optimize RX sensitivity */ | ||
69 | return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42); | ||
70 | } | ||
71 | |||
72 | static int rts5227_turn_on_led(struct rtsx_pcr *pcr) | ||
73 | { | ||
74 | return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02); | ||
75 | } | ||
76 | |||
77 | static int rts5227_turn_off_led(struct rtsx_pcr *pcr) | ||
78 | { | ||
79 | return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00); | ||
80 | } | ||
81 | |||
82 | static int rts5227_enable_auto_blink(struct rtsx_pcr *pcr) | ||
83 | { | ||
84 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08); | ||
85 | } | ||
86 | |||
87 | static int rts5227_disable_auto_blink(struct rtsx_pcr *pcr) | ||
88 | { | ||
89 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00); | ||
90 | } | ||
91 | |||
92 | static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card) | ||
93 | { | ||
94 | int err; | ||
95 | |||
96 | rtsx_pci_init_cmd(pcr); | ||
97 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, | ||
98 | SD_POWER_MASK, SD_PARTIAL_POWER_ON); | ||
99 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, | ||
100 | LDO3318_PWR_MASK, 0x02); | ||
101 | err = rtsx_pci_send_cmd(pcr, 100); | ||
102 | if (err < 0) | ||
103 | return err; | ||
104 | |||
105 | /* To avoid too large in-rush current */ | ||
106 | udelay(150); | ||
107 | |||
108 | rtsx_pci_init_cmd(pcr); | ||
109 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, | ||
110 | SD_POWER_MASK, SD_POWER_ON); | ||
111 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, | ||
112 | LDO3318_PWR_MASK, 0x06); | ||
113 | err = rtsx_pci_send_cmd(pcr, 100); | ||
114 | if (err < 0) | ||
115 | return err; | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card) | ||
121 | { | ||
122 | rtsx_pci_init_cmd(pcr); | ||
123 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, | ||
124 | SD_POWER_MASK | PMOS_STRG_MASK, | ||
125 | SD_POWER_OFF | PMOS_STRG_400mA); | ||
126 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, | ||
127 | LDO3318_PWR_MASK, 0X00); | ||
128 | return rtsx_pci_send_cmd(pcr, 100); | ||
129 | } | ||
130 | |||
131 | static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | ||
132 | { | ||
133 | int err; | ||
134 | u8 drive_sel; | ||
135 | |||
136 | if (voltage == OUTPUT_3V3) { | ||
137 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | ||
138 | if (err < 0) | ||
139 | return err; | ||
140 | drive_sel = 0x96; | ||
141 | } else if (voltage == OUTPUT_1V8) { | ||
142 | err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02); | ||
143 | if (err < 0) | ||
144 | return err; | ||
145 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24); | ||
146 | if (err < 0) | ||
147 | return err; | ||
148 | drive_sel = 0xB3; | ||
149 | } else { | ||
150 | return -EINVAL; | ||
151 | } | ||
152 | |||
153 | /* set pad drive */ | ||
154 | rtsx_pci_init_cmd(pcr); | ||
155 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, | ||
156 | 0xFF, drive_sel); | ||
157 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL, | ||
158 | 0xFF, drive_sel); | ||
159 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL, | ||
160 | 0xFF, drive_sel); | ||
161 | return rtsx_pci_send_cmd(pcr, 100); | ||
162 | } | ||
163 | |||
164 | static const struct pcr_ops rts5227_pcr_ops = { | ||
165 | .extra_init_hw = rts5227_extra_init_hw, | ||
166 | .optimize_phy = rts5227_optimize_phy, | ||
167 | .turn_on_led = rts5227_turn_on_led, | ||
168 | .turn_off_led = rts5227_turn_off_led, | ||
169 | .enable_auto_blink = rts5227_enable_auto_blink, | ||
170 | .disable_auto_blink = rts5227_disable_auto_blink, | ||
171 | .card_power_on = rts5227_card_power_on, | ||
172 | .card_power_off = rts5227_card_power_off, | ||
173 | .switch_output_voltage = rts5227_switch_output_voltage, | ||
174 | .cd_deglitch = NULL, | ||
175 | .conv_clk_and_div_n = NULL, | ||
176 | }; | ||
177 | |||
178 | /* SD Pull Control Enable: | ||
179 | * SD_DAT[3:0] ==> pull up | ||
180 | * SD_CD ==> pull up | ||
181 | * SD_WP ==> pull up | ||
182 | * SD_CMD ==> pull up | ||
183 | * SD_CLK ==> pull down | ||
184 | */ | ||
185 | static const u32 rts5227_sd_pull_ctl_enable_tbl[] = { | ||
186 | RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), | ||
187 | RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9), | ||
188 | 0, | ||
189 | }; | ||
190 | |||
191 | /* SD Pull Control Disable: | ||
192 | * SD_DAT[3:0] ==> pull down | ||
193 | * SD_CD ==> pull up | ||
194 | * SD_WP ==> pull down | ||
195 | * SD_CMD ==> pull down | ||
196 | * SD_CLK ==> pull down | ||
197 | */ | ||
198 | static const u32 rts5227_sd_pull_ctl_disable_tbl[] = { | ||
199 | RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), | ||
200 | RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5), | ||
201 | 0, | ||
202 | }; | ||
203 | |||
204 | /* MS Pull Control Enable: | ||
205 | * MS CD ==> pull up | ||
206 | * others ==> pull down | ||
207 | */ | ||
208 | static const u32 rts5227_ms_pull_ctl_enable_tbl[] = { | ||
209 | RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), | ||
210 | RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), | ||
211 | 0, | ||
212 | }; | ||
213 | |||
214 | /* MS Pull Control Disable: | ||
215 | * MS CD ==> pull up | ||
216 | * others ==> pull down | ||
217 | */ | ||
218 | static const u32 rts5227_ms_pull_ctl_disable_tbl[] = { | ||
219 | RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), | ||
220 | RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), | ||
221 | 0, | ||
222 | }; | ||
223 | |||
224 | void rts5227_init_params(struct rtsx_pcr *pcr) | ||
225 | { | ||
226 | pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104; | ||
227 | pcr->num_slots = 2; | ||
228 | pcr->ops = &rts5227_pcr_ops; | ||
229 | |||
230 | pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl; | ||
231 | pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl; | ||
232 | pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl; | ||
233 | pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl; | ||
234 | } | ||
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c index b9dbab266fda..58af4dbe3586 100644 --- a/drivers/mfd/rts5229.c +++ b/drivers/mfd/rts5229.c | |||
@@ -114,6 +114,33 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card) | |||
114 | return rtsx_pci_send_cmd(pcr, 100); | 114 | return rtsx_pci_send_cmd(pcr, 100); |
115 | } | 115 | } |
116 | 116 | ||
117 | static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | ||
118 | { | ||
119 | int err; | ||
120 | |||
121 | if (voltage == OUTPUT_3V3) { | ||
122 | err = rtsx_pci_write_register(pcr, | ||
123 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); | ||
124 | if (err < 0) | ||
125 | return err; | ||
126 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | ||
127 | if (err < 0) | ||
128 | return err; | ||
129 | } else if (voltage == OUTPUT_1V8) { | ||
130 | err = rtsx_pci_write_register(pcr, | ||
131 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); | ||
132 | if (err < 0) | ||
133 | return err; | ||
134 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); | ||
135 | if (err < 0) | ||
136 | return err; | ||
137 | } else { | ||
138 | return -EINVAL; | ||
139 | } | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
117 | static const struct pcr_ops rts5229_pcr_ops = { | 144 | static const struct pcr_ops rts5229_pcr_ops = { |
118 | .extra_init_hw = rts5229_extra_init_hw, | 145 | .extra_init_hw = rts5229_extra_init_hw, |
119 | .optimize_phy = rts5229_optimize_phy, | 146 | .optimize_phy = rts5229_optimize_phy, |
@@ -123,7 +150,9 @@ static const struct pcr_ops rts5229_pcr_ops = { | |||
123 | .disable_auto_blink = rts5229_disable_auto_blink, | 150 | .disable_auto_blink = rts5229_disable_auto_blink, |
124 | .card_power_on = rts5229_card_power_on, | 151 | .card_power_on = rts5229_card_power_on, |
125 | .card_power_off = rts5229_card_power_off, | 152 | .card_power_off = rts5229_card_power_off, |
153 | .switch_output_voltage = rts5229_switch_output_voltage, | ||
126 | .cd_deglitch = NULL, | 154 | .cd_deglitch = NULL, |
155 | .conv_clk_and_div_n = NULL, | ||
127 | }; | 156 | }; |
128 | 157 | ||
129 | /* SD Pull Control Enable: | 158 | /* SD Pull Control Enable: |
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 7a7b0bda4618..822237e322ba 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -55,6 +55,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_ids) = { | |||
55 | { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 55 | { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
56 | { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 56 | { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
57 | { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 57 | { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
58 | { PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | ||
58 | { 0, } | 59 | { 0, } |
59 | }; | 60 | }; |
60 | 61 | ||
@@ -325,7 +326,6 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr, | |||
325 | val = ((u64)addr << 32) | ((u64)len << 12) | option; | 326 | val = ((u64)addr << 32) | ((u64)len << 12) | option; |
326 | 327 | ||
327 | put_unaligned_le64(val, ptr); | 328 | put_unaligned_le64(val, ptr); |
328 | ptr++; | ||
329 | pcr->sgi++; | 329 | pcr->sgi++; |
330 | } | 330 | } |
331 | 331 | ||
@@ -591,8 +591,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
591 | u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk) | 591 | u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk) |
592 | { | 592 | { |
593 | int err, clk; | 593 | int err, clk; |
594 | u8 N, min_N, max_N, clk_divider; | 594 | u8 n, clk_divider, mcu_cnt, div; |
595 | u8 mcu_cnt, div, max_div; | ||
596 | u8 depth[] = { | 595 | u8 depth[] = { |
597 | [RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M, | 596 | [RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M, |
598 | [RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M, | 597 | [RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M, |
@@ -616,10 +615,6 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
616 | card_clock /= 1000000; | 615 | card_clock /= 1000000; |
617 | dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock); | 616 | dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock); |
618 | 617 | ||
619 | min_N = 80; | ||
620 | max_N = 208; | ||
621 | max_div = CLK_DIV_8; | ||
622 | |||
623 | clk = card_clock; | 618 | clk = card_clock; |
624 | if (!initial_mode && double_clk) | 619 | if (!initial_mode && double_clk) |
625 | clk = card_clock * 2; | 620 | clk = card_clock * 2; |
@@ -630,21 +625,31 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
630 | if (clk == pcr->cur_clock) | 625 | if (clk == pcr->cur_clock) |
631 | return 0; | 626 | return 0; |
632 | 627 | ||
633 | N = (u8)(clk - 2); | 628 | if (pcr->ops->conv_clk_and_div_n) |
634 | if ((clk <= 2) || (N > max_N)) | 629 | n = (u8)pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N); |
630 | else | ||
631 | n = (u8)(clk - 2); | ||
632 | if ((clk <= 2) || (n > MAX_DIV_N_PCR)) | ||
635 | return -EINVAL; | 633 | return -EINVAL; |
636 | 634 | ||
637 | mcu_cnt = (u8)(125/clk + 3); | 635 | mcu_cnt = (u8)(125/clk + 3); |
638 | if (mcu_cnt > 15) | 636 | if (mcu_cnt > 15) |
639 | mcu_cnt = 15; | 637 | mcu_cnt = 15; |
640 | 638 | ||
641 | /* Make sure that the SSC clock div_n is equal or greater than min_N */ | 639 | /* Make sure that the SSC clock div_n is not less than MIN_DIV_N_PCR */ |
642 | div = CLK_DIV_1; | 640 | div = CLK_DIV_1; |
643 | while ((N < min_N) && (div < max_div)) { | 641 | while ((n < MIN_DIV_N_PCR) && (div < CLK_DIV_8)) { |
644 | N = (N + 2) * 2 - 2; | 642 | if (pcr->ops->conv_clk_and_div_n) { |
643 | int dbl_clk = pcr->ops->conv_clk_and_div_n(n, | ||
644 | DIV_N_TO_CLK) * 2; | ||
645 | n = (u8)pcr->ops->conv_clk_and_div_n(dbl_clk, | ||
646 | CLK_TO_DIV_N); | ||
647 | } else { | ||
648 | n = (n + 2) * 2 - 2; | ||
649 | } | ||
645 | div++; | 650 | div++; |
646 | } | 651 | } |
647 | dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div); | 652 | dev_dbg(&(pcr->pci->dev), "n = %d, div = %d\n", n, div); |
648 | 653 | ||
649 | ssc_depth = depth[ssc_depth]; | 654 | ssc_depth = depth[ssc_depth]; |
650 | if (double_clk) | 655 | if (double_clk) |
@@ -661,7 +666,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
661 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); | 666 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); |
662 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, | 667 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, |
663 | SSC_DEPTH_MASK, ssc_depth); | 668 | SSC_DEPTH_MASK, ssc_depth); |
664 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); | 669 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n); |
665 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); | 670 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); |
666 | if (vpclk) { | 671 | if (vpclk) { |
667 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, | 672 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, |
@@ -703,6 +708,15 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card) | |||
703 | } | 708 | } |
704 | EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); | 709 | EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); |
705 | 710 | ||
711 | int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | ||
712 | { | ||
713 | if (pcr->ops->switch_output_voltage) | ||
714 | return pcr->ops->switch_output_voltage(pcr, voltage); | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | EXPORT_SYMBOL_GPL(rtsx_pci_switch_output_voltage); | ||
719 | |||
706 | unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr) | 720 | unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr) |
707 | { | 721 | { |
708 | unsigned int val; | 722 | unsigned int val; |
@@ -739,7 +753,7 @@ static void rtsx_pci_card_detect(struct work_struct *work) | |||
739 | struct delayed_work *dwork; | 753 | struct delayed_work *dwork; |
740 | struct rtsx_pcr *pcr; | 754 | struct rtsx_pcr *pcr; |
741 | unsigned long flags; | 755 | unsigned long flags; |
742 | unsigned int card_detect = 0; | 756 | unsigned int card_detect = 0, card_inserted, card_removed; |
743 | u32 irq_status; | 757 | u32 irq_status; |
744 | 758 | ||
745 | dwork = to_delayed_work(work); | 759 | dwork = to_delayed_work(work); |
@@ -747,30 +761,37 @@ static void rtsx_pci_card_detect(struct work_struct *work) | |||
747 | 761 | ||
748 | dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__); | 762 | dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__); |
749 | 763 | ||
764 | mutex_lock(&pcr->pcr_mutex); | ||
750 | spin_lock_irqsave(&pcr->lock, flags); | 765 | spin_lock_irqsave(&pcr->lock, flags); |
751 | 766 | ||
752 | irq_status = rtsx_pci_readl(pcr, RTSX_BIPR); | 767 | irq_status = rtsx_pci_readl(pcr, RTSX_BIPR); |
753 | dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status); | 768 | dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status); |
754 | 769 | ||
755 | if (pcr->card_inserted || pcr->card_removed) { | 770 | irq_status &= CARD_EXIST; |
771 | card_inserted = pcr->card_inserted & irq_status; | ||
772 | card_removed = pcr->card_removed; | ||
773 | pcr->card_inserted = 0; | ||
774 | pcr->card_removed = 0; | ||
775 | |||
776 | spin_unlock_irqrestore(&pcr->lock, flags); | ||
777 | |||
778 | if (card_inserted || card_removed) { | ||
756 | dev_dbg(&(pcr->pci->dev), | 779 | dev_dbg(&(pcr->pci->dev), |
757 | "card_inserted: 0x%x, card_removed: 0x%x\n", | 780 | "card_inserted: 0x%x, card_removed: 0x%x\n", |
758 | pcr->card_inserted, pcr->card_removed); | 781 | card_inserted, card_removed); |
759 | 782 | ||
760 | if (pcr->ops->cd_deglitch) | 783 | if (pcr->ops->cd_deglitch) |
761 | pcr->card_inserted = pcr->ops->cd_deglitch(pcr); | 784 | card_inserted = pcr->ops->cd_deglitch(pcr); |
762 | 785 | ||
763 | card_detect = pcr->card_inserted | pcr->card_removed; | 786 | card_detect = card_inserted | card_removed; |
764 | pcr->card_inserted = 0; | ||
765 | pcr->card_removed = 0; | ||
766 | } | 787 | } |
767 | 788 | ||
768 | spin_unlock_irqrestore(&pcr->lock, flags); | 789 | mutex_unlock(&pcr->pcr_mutex); |
769 | 790 | ||
770 | if (card_detect & SD_EXIST) | 791 | if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event) |
771 | pcr->slots[RTSX_SD_CARD].card_event( | 792 | pcr->slots[RTSX_SD_CARD].card_event( |
772 | pcr->slots[RTSX_SD_CARD].p_dev); | 793 | pcr->slots[RTSX_SD_CARD].p_dev); |
773 | if (card_detect & MS_EXIST) | 794 | if ((card_detect & MS_EXIST) && pcr->slots[RTSX_MS_CARD].card_event) |
774 | pcr->slots[RTSX_MS_CARD].card_event( | 795 | pcr->slots[RTSX_MS_CARD].card_event( |
775 | pcr->slots[RTSX_MS_CARD].p_dev); | 796 | pcr->slots[RTSX_MS_CARD].p_dev); |
776 | } | 797 | } |
@@ -817,10 +838,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
817 | } | 838 | } |
818 | } | 839 | } |
819 | 840 | ||
820 | if (pcr->card_inserted || pcr->card_removed) | ||
821 | schedule_delayed_work(&pcr->carddet_work, | ||
822 | msecs_to_jiffies(200)); | ||
823 | |||
824 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { | 841 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { |
825 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { | 842 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { |
826 | pcr->trans_result = TRANS_RESULT_FAIL; | 843 | pcr->trans_result = TRANS_RESULT_FAIL; |
@@ -833,6 +850,10 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
833 | } | 850 | } |
834 | } | 851 | } |
835 | 852 | ||
853 | if (pcr->card_inserted || pcr->card_removed) | ||
854 | schedule_delayed_work(&pcr->carddet_work, | ||
855 | msecs_to_jiffies(200)); | ||
856 | |||
836 | spin_unlock(&pcr->lock); | 857 | spin_unlock(&pcr->lock); |
837 | return IRQ_HANDLED; | 858 | return IRQ_HANDLED; |
838 | } | 859 | } |
@@ -978,6 +999,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) | |||
978 | case 0x5289: | 999 | case 0x5289: |
979 | rtl8411_init_params(pcr); | 1000 | rtl8411_init_params(pcr); |
980 | break; | 1001 | break; |
1002 | |||
1003 | case 0x5227: | ||
1004 | rts5227_init_params(pcr); | ||
1005 | break; | ||
981 | } | 1006 | } |
982 | 1007 | ||
983 | dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n", | 1008 | dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n", |
@@ -1011,6 +1036,10 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, | |||
1011 | pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device, | 1036 | pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device, |
1012 | (int)pcidev->revision); | 1037 | (int)pcidev->revision); |
1013 | 1038 | ||
1039 | ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)); | ||
1040 | if (ret < 0) | ||
1041 | return ret; | ||
1042 | |||
1014 | ret = pci_enable_device(pcidev); | 1043 | ret = pci_enable_device(pcidev); |
1015 | if (ret) | 1044 | if (ret) |
1016 | return ret; | 1045 | return ret; |
diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h index 12462c1df1a9..2b3ab8a04823 100644 --- a/drivers/mfd/rtsx_pcr.h +++ b/drivers/mfd/rtsx_pcr.h | |||
@@ -25,8 +25,12 @@ | |||
25 | 25 | ||
26 | #include <linux/mfd/rtsx_pci.h> | 26 | #include <linux/mfd/rtsx_pci.h> |
27 | 27 | ||
28 | #define MIN_DIV_N_PCR 80 | ||
29 | #define MAX_DIV_N_PCR 208 | ||
30 | |||
28 | void rts5209_init_params(struct rtsx_pcr *pcr); | 31 | void rts5209_init_params(struct rtsx_pcr *pcr); |
29 | void rts5229_init_params(struct rtsx_pcr *pcr); | 32 | void rts5229_init_params(struct rtsx_pcr *pcr); |
30 | void rtl8411_init_params(struct rtsx_pcr *pcr); | 33 | void rtl8411_init_params(struct rtsx_pcr *pcr); |
34 | void rts5227_init_params(struct rtsx_pcr *pcr); | ||
31 | 35 | ||
32 | #endif | 36 | #endif |
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index a06d66b929b1..ecc092c7f745 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -219,25 +219,18 @@ static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | static struct irq_domain_ops tc3589x_irq_ops = { | 221 | static struct irq_domain_ops tc3589x_irq_ops = { |
222 | .map = tc3589x_irq_map, | 222 | .map = tc3589x_irq_map, |
223 | .unmap = tc3589x_irq_unmap, | 223 | .unmap = tc3589x_irq_unmap, |
224 | .xlate = irq_domain_xlate_twocell, | 224 | .xlate = irq_domain_xlate_twocell, |
225 | }; | 225 | }; |
226 | 226 | ||
227 | static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np) | 227 | static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np) |
228 | { | 228 | { |
229 | int base = tc3589x->irq_base; | 229 | int base = tc3589x->irq_base; |
230 | 230 | ||
231 | if (base) { | 231 | tc3589x->domain = irq_domain_add_simple( |
232 | tc3589x->domain = irq_domain_add_legacy( | 232 | np, TC3589x_NR_INTERNAL_IRQS, base, |
233 | NULL, TC3589x_NR_INTERNAL_IRQS, base, | 233 | &tc3589x_irq_ops, tc3589x); |
234 | 0, &tc3589x_irq_ops, tc3589x); | ||
235 | } | ||
236 | else { | ||
237 | tc3589x->domain = irq_domain_add_linear( | ||
238 | np, TC3589x_NR_INTERNAL_IRQS, | ||
239 | &tc3589x_irq_ops, tc3589x); | ||
240 | } | ||
241 | 234 | ||
242 | if (!tc3589x->domain) { | 235 | if (!tc3589x->domain) { |
243 | dev_err(tc3589x->dev, "Failed to create irqdomain\n"); | 236 | dev_err(tc3589x->dev, "Failed to create irqdomain\n"); |
diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 409afa23d5dc..5ad4b772b097 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/of_device.h> | ||
22 | #include <linux/mfd/core.h> | 23 | #include <linux/mfd/core.h> |
23 | #include <linux/mfd/tps6507x.h> | 24 | #include <linux/mfd/tps6507x.h> |
24 | 25 | ||
@@ -116,11 +117,19 @@ static const struct i2c_device_id tps6507x_i2c_id[] = { | |||
116 | }; | 117 | }; |
117 | MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id); | 118 | MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id); |
118 | 119 | ||
120 | #ifdef CONFIG_OF | ||
121 | static struct of_device_id tps6507x_of_match[] = { | ||
122 | {.compatible = "ti,tps6507x", }, | ||
123 | {}, | ||
124 | }; | ||
125 | MODULE_DEVICE_TABLE(of, tps6507x_of_match); | ||
126 | #endif | ||
119 | 127 | ||
120 | static struct i2c_driver tps6507x_i2c_driver = { | 128 | static struct i2c_driver tps6507x_i2c_driver = { |
121 | .driver = { | 129 | .driver = { |
122 | .name = "tps6507x", | 130 | .name = "tps6507x", |
123 | .owner = THIS_MODULE, | 131 | .owner = THIS_MODULE, |
132 | .of_match_table = of_match_ptr(tps6507x_of_match), | ||
124 | }, | 133 | }, |
125 | .probe = tps6507x_i2c_probe, | 134 | .probe = tps6507x_i2c_probe, |
126 | .remove = tps6507x_i2c_remove, | 135 | .remove = tps6507x_i2c_remove, |
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 8d12a8e00d9c..98edb5be85c6 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/mfd/core.h> | 26 | #include <linux/mfd/core.h> |
27 | #include <linux/mfd/tps65090.h> | 27 | #include <linux/mfd/tps65090.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/of_device.h> | ||
28 | #include <linux/err.h> | 30 | #include <linux/err.h> |
29 | 31 | ||
30 | #define NUM_INT_REG 2 | 32 | #define NUM_INT_REG 2 |
@@ -148,18 +150,31 @@ static const struct regmap_config tps65090_regmap_config = { | |||
148 | .volatile_reg = is_volatile_reg, | 150 | .volatile_reg = is_volatile_reg, |
149 | }; | 151 | }; |
150 | 152 | ||
153 | #ifdef CONFIG_OF | ||
154 | static const struct of_device_id tps65090_of_match[] = { | ||
155 | { .compatible = "ti,tps65090",}, | ||
156 | {}, | ||
157 | }; | ||
158 | MODULE_DEVICE_TABLE(of, tps65090_of_match); | ||
159 | #endif | ||
160 | |||
151 | static int tps65090_i2c_probe(struct i2c_client *client, | 161 | static int tps65090_i2c_probe(struct i2c_client *client, |
152 | const struct i2c_device_id *id) | 162 | const struct i2c_device_id *id) |
153 | { | 163 | { |
154 | struct tps65090_platform_data *pdata = client->dev.platform_data; | 164 | struct tps65090_platform_data *pdata = client->dev.platform_data; |
165 | int irq_base = 0; | ||
155 | struct tps65090 *tps65090; | 166 | struct tps65090 *tps65090; |
156 | int ret; | 167 | int ret; |
157 | 168 | ||
158 | if (!pdata) { | 169 | if (!pdata && !client->dev.of_node) { |
159 | dev_err(&client->dev, "tps65090 requires platform data\n"); | 170 | dev_err(&client->dev, |
171 | "tps65090 requires platform data or of_node\n"); | ||
160 | return -EINVAL; | 172 | return -EINVAL; |
161 | } | 173 | } |
162 | 174 | ||
175 | if (pdata) | ||
176 | irq_base = pdata->irq_base; | ||
177 | |||
163 | tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL); | 178 | tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL); |
164 | if (!tps65090) { | 179 | if (!tps65090) { |
165 | dev_err(&client->dev, "mem alloc for tps65090 failed\n"); | 180 | dev_err(&client->dev, "mem alloc for tps65090 failed\n"); |
@@ -178,7 +193,7 @@ static int tps65090_i2c_probe(struct i2c_client *client, | |||
178 | 193 | ||
179 | if (client->irq) { | 194 | if (client->irq) { |
180 | ret = regmap_add_irq_chip(tps65090->rmap, client->irq, | 195 | ret = regmap_add_irq_chip(tps65090->rmap, client->irq, |
181 | IRQF_ONESHOT | IRQF_TRIGGER_LOW, pdata->irq_base, | 196 | IRQF_ONESHOT | IRQF_TRIGGER_LOW, irq_base, |
182 | &tps65090_irq_chip, &tps65090->irq_data); | 197 | &tps65090_irq_chip, &tps65090->irq_data); |
183 | if (ret) { | 198 | if (ret) { |
184 | dev_err(&client->dev, | 199 | dev_err(&client->dev, |
@@ -189,7 +204,7 @@ static int tps65090_i2c_probe(struct i2c_client *client, | |||
189 | 204 | ||
190 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, | 205 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, |
191 | ARRAY_SIZE(tps65090s), NULL, | 206 | ARRAY_SIZE(tps65090s), NULL, |
192 | regmap_irq_chip_get_base(tps65090->irq_data), NULL); | 207 | 0, regmap_irq_get_domain(tps65090->irq_data)); |
193 | if (ret) { | 208 | if (ret) { |
194 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", | 209 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", |
195 | ret); | 210 | ret); |
@@ -215,28 +230,6 @@ static int tps65090_i2c_remove(struct i2c_client *client) | |||
215 | return 0; | 230 | return 0; |
216 | } | 231 | } |
217 | 232 | ||
218 | #ifdef CONFIG_PM_SLEEP | ||
219 | static int tps65090_suspend(struct device *dev) | ||
220 | { | ||
221 | struct i2c_client *client = to_i2c_client(dev); | ||
222 | if (client->irq) | ||
223 | disable_irq(client->irq); | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int tps65090_resume(struct device *dev) | ||
228 | { | ||
229 | struct i2c_client *client = to_i2c_client(dev); | ||
230 | if (client->irq) | ||
231 | enable_irq(client->irq); | ||
232 | return 0; | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | static const struct dev_pm_ops tps65090_pm_ops = { | ||
237 | SET_SYSTEM_SLEEP_PM_OPS(tps65090_suspend, tps65090_resume) | ||
238 | }; | ||
239 | |||
240 | static const struct i2c_device_id tps65090_id_table[] = { | 233 | static const struct i2c_device_id tps65090_id_table[] = { |
241 | { "tps65090", 0 }, | 234 | { "tps65090", 0 }, |
242 | { }, | 235 | { }, |
@@ -247,7 +240,7 @@ static struct i2c_driver tps65090_driver = { | |||
247 | .driver = { | 240 | .driver = { |
248 | .name = "tps65090", | 241 | .name = "tps65090", |
249 | .owner = THIS_MODULE, | 242 | .owner = THIS_MODULE, |
250 | .pm = &tps65090_pm_ops, | 243 | .of_match_table = of_match_ptr(tps65090_of_match), |
251 | }, | 244 | }, |
252 | .probe = tps65090_i2c_probe, | 245 | .probe = tps65090_i2c_probe, |
253 | .remove = tps65090_i2c_remove, | 246 | .remove = tps65090_i2c_remove, |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 4f3baadd0038..557f9ee5ec18 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -66,16 +66,6 @@ | |||
66 | 66 | ||
67 | /* Triton Core internal information (BEGIN) */ | 67 | /* Triton Core internal information (BEGIN) */ |
68 | 68 | ||
69 | #define TWL_NUM_SLAVES 4 | ||
70 | |||
71 | #define SUB_CHIP_ID0 0 | ||
72 | #define SUB_CHIP_ID1 1 | ||
73 | #define SUB_CHIP_ID2 2 | ||
74 | #define SUB_CHIP_ID3 3 | ||
75 | #define SUB_CHIP_ID_INVAL 0xff | ||
76 | |||
77 | #define TWL_MODULE_LAST TWL4030_MODULE_LAST | ||
78 | |||
79 | /* Base Address defns for twl4030_map[] */ | 69 | /* Base Address defns for twl4030_map[] */ |
80 | 70 | ||
81 | /* subchip/slave 0 - USB ID */ | 71 | /* subchip/slave 0 - USB ID */ |
@@ -94,10 +84,7 @@ | |||
94 | #define TWL4030_BASEADD_MADC 0x0000 | 84 | #define TWL4030_BASEADD_MADC 0x0000 |
95 | #define TWL4030_BASEADD_MAIN_CHARGE 0x0074 | 85 | #define TWL4030_BASEADD_MAIN_CHARGE 0x0074 |
96 | #define TWL4030_BASEADD_PRECHARGE 0x00AA | 86 | #define TWL4030_BASEADD_PRECHARGE 0x00AA |
97 | #define TWL4030_BASEADD_PWM0 0x00F8 | 87 | #define TWL4030_BASEADD_PWM 0x00F8 |
98 | #define TWL4030_BASEADD_PWM1 0x00FB | ||
99 | #define TWL4030_BASEADD_PWMA 0x00EF | ||
100 | #define TWL4030_BASEADD_PWMB 0x00F1 | ||
101 | #define TWL4030_BASEADD_KEYPAD 0x00D2 | 88 | #define TWL4030_BASEADD_KEYPAD 0x00D2 |
102 | 89 | ||
103 | #define TWL5031_BASEADD_ACCESSORY 0x0074 /* Replaces Main Charge */ | 90 | #define TWL5031_BASEADD_ACCESSORY 0x0074 /* Replaces Main Charge */ |
@@ -117,7 +104,7 @@ | |||
117 | 104 | ||
118 | /* subchip/slave 0 0x48 - POWER */ | 105 | /* subchip/slave 0 0x48 - POWER */ |
119 | #define TWL6030_BASEADD_RTC 0x0000 | 106 | #define TWL6030_BASEADD_RTC 0x0000 |
120 | #define TWL6030_BASEADD_MEM 0x0017 | 107 | #define TWL6030_BASEADD_SECURED_REG 0x0017 |
121 | #define TWL6030_BASEADD_PM_MASTER 0x001F | 108 | #define TWL6030_BASEADD_PM_MASTER 0x001F |
122 | #define TWL6030_BASEADD_PM_SLAVE_MISC 0x0030 /* PM_RECEIVER */ | 109 | #define TWL6030_BASEADD_PM_SLAVE_MISC 0x0030 /* PM_RECEIVER */ |
123 | #define TWL6030_BASEADD_PM_MISC 0x00E2 | 110 | #define TWL6030_BASEADD_PM_MISC 0x00E2 |
@@ -132,6 +119,7 @@ | |||
132 | #define TWL6030_BASEADD_PIH 0x00D0 | 119 | #define TWL6030_BASEADD_PIH 0x00D0 |
133 | #define TWL6030_BASEADD_CHARGER 0x00E0 | 120 | #define TWL6030_BASEADD_CHARGER 0x00E0 |
134 | #define TWL6025_BASEADD_CHARGER 0x00DA | 121 | #define TWL6025_BASEADD_CHARGER 0x00DA |
122 | #define TWL6030_BASEADD_LED 0x00F4 | ||
135 | 123 | ||
136 | /* subchip/slave 2 0x4A - DFT */ | 124 | /* subchip/slave 2 0x4A - DFT */ |
137 | #define TWL6030_BASEADD_DIEID 0x00C0 | 125 | #define TWL6030_BASEADD_DIEID 0x00C0 |
@@ -153,33 +141,28 @@ | |||
153 | 141 | ||
154 | /*----------------------------------------------------------------------*/ | 142 | /*----------------------------------------------------------------------*/ |
155 | 143 | ||
156 | /* is driver active, bound to a chip? */ | ||
157 | static bool inuse; | ||
158 | |||
159 | /* TWL IDCODE Register value */ | ||
160 | static u32 twl_idcode; | ||
161 | |||
162 | static unsigned int twl_id; | ||
163 | unsigned int twl_rev(void) | ||
164 | { | ||
165 | return twl_id; | ||
166 | } | ||
167 | EXPORT_SYMBOL(twl_rev); | ||
168 | |||
169 | /* Structure for each TWL4030/TWL6030 Slave */ | 144 | /* Structure for each TWL4030/TWL6030 Slave */ |
170 | struct twl_client { | 145 | struct twl_client { |
171 | struct i2c_client *client; | 146 | struct i2c_client *client; |
172 | struct regmap *regmap; | 147 | struct regmap *regmap; |
173 | }; | 148 | }; |
174 | 149 | ||
175 | static struct twl_client twl_modules[TWL_NUM_SLAVES]; | ||
176 | |||
177 | /* mapping the module id to slave id and base address */ | 150 | /* mapping the module id to slave id and base address */ |
178 | struct twl_mapping { | 151 | struct twl_mapping { |
179 | unsigned char sid; /* Slave ID */ | 152 | unsigned char sid; /* Slave ID */ |
180 | unsigned char base; /* base address */ | 153 | unsigned char base; /* base address */ |
181 | }; | 154 | }; |
182 | static struct twl_mapping *twl_map; | 155 | |
156 | struct twl_private { | ||
157 | bool ready; /* The core driver is ready to be used */ | ||
158 | u32 twl_idcode; /* TWL IDCODE Register value */ | ||
159 | unsigned int twl_id; | ||
160 | |||
161 | struct twl_mapping *twl_map; | ||
162 | struct twl_client *twl_modules; | ||
163 | }; | ||
164 | |||
165 | static struct twl_private *twl_priv; | ||
183 | 166 | ||
184 | static struct twl_mapping twl4030_map[] = { | 167 | static struct twl_mapping twl4030_map[] = { |
185 | /* | 168 | /* |
@@ -188,34 +171,33 @@ static struct twl_mapping twl4030_map[] = { | |||
188 | * so they continue to match the order in this table. | 171 | * so they continue to match the order in this table. |
189 | */ | 172 | */ |
190 | 173 | ||
174 | /* Common IPs */ | ||
191 | { 0, TWL4030_BASEADD_USB }, | 175 | { 0, TWL4030_BASEADD_USB }, |
176 | { 1, TWL4030_BASEADD_PIH }, | ||
177 | { 2, TWL4030_BASEADD_MAIN_CHARGE }, | ||
178 | { 3, TWL4030_BASEADD_PM_MASTER }, | ||
179 | { 3, TWL4030_BASEADD_PM_RECEIVER }, | ||
180 | |||
181 | { 3, TWL4030_BASEADD_RTC }, | ||
182 | { 2, TWL4030_BASEADD_PWM }, | ||
183 | { 2, TWL4030_BASEADD_LED }, | ||
184 | { 3, TWL4030_BASEADD_SECURED_REG }, | ||
185 | |||
186 | /* TWL4030 specific IPs */ | ||
192 | { 1, TWL4030_BASEADD_AUDIO_VOICE }, | 187 | { 1, TWL4030_BASEADD_AUDIO_VOICE }, |
193 | { 1, TWL4030_BASEADD_GPIO }, | 188 | { 1, TWL4030_BASEADD_GPIO }, |
194 | { 1, TWL4030_BASEADD_INTBR }, | 189 | { 1, TWL4030_BASEADD_INTBR }, |
195 | { 1, TWL4030_BASEADD_PIH }, | ||
196 | |||
197 | { 1, TWL4030_BASEADD_TEST }, | 190 | { 1, TWL4030_BASEADD_TEST }, |
198 | { 2, TWL4030_BASEADD_KEYPAD }, | 191 | { 2, TWL4030_BASEADD_KEYPAD }, |
192 | |||
199 | { 2, TWL4030_BASEADD_MADC }, | 193 | { 2, TWL4030_BASEADD_MADC }, |
200 | { 2, TWL4030_BASEADD_INTERRUPTS }, | 194 | { 2, TWL4030_BASEADD_INTERRUPTS }, |
201 | { 2, TWL4030_BASEADD_LED }, | ||
202 | |||
203 | { 2, TWL4030_BASEADD_MAIN_CHARGE }, | ||
204 | { 2, TWL4030_BASEADD_PRECHARGE }, | 195 | { 2, TWL4030_BASEADD_PRECHARGE }, |
205 | { 2, TWL4030_BASEADD_PWM0 }, | ||
206 | { 2, TWL4030_BASEADD_PWM1 }, | ||
207 | { 2, TWL4030_BASEADD_PWMA }, | ||
208 | |||
209 | { 2, TWL4030_BASEADD_PWMB }, | ||
210 | { 2, TWL5031_BASEADD_ACCESSORY }, | ||
211 | { 2, TWL5031_BASEADD_INTERRUPTS }, | ||
212 | { 3, TWL4030_BASEADD_BACKUP }, | 196 | { 3, TWL4030_BASEADD_BACKUP }, |
213 | { 3, TWL4030_BASEADD_INT }, | 197 | { 3, TWL4030_BASEADD_INT }, |
214 | 198 | ||
215 | { 3, TWL4030_BASEADD_PM_MASTER }, | 199 | { 2, TWL5031_BASEADD_ACCESSORY }, |
216 | { 3, TWL4030_BASEADD_PM_RECEIVER }, | 200 | { 2, TWL5031_BASEADD_INTERRUPTS }, |
217 | { 3, TWL4030_BASEADD_RTC }, | ||
218 | { 3, TWL4030_BASEADD_SECURED_REG }, | ||
219 | }; | 201 | }; |
220 | 202 | ||
221 | static struct regmap_config twl4030_regmap_config[4] = { | 203 | static struct regmap_config twl4030_regmap_config[4] = { |
@@ -251,35 +233,25 @@ static struct twl_mapping twl6030_map[] = { | |||
251 | * <linux/i2c/twl.h> defines for TWL4030_MODULE_* | 233 | * <linux/i2c/twl.h> defines for TWL4030_MODULE_* |
252 | * so they continue to match the order in this table. | 234 | * so they continue to match the order in this table. |
253 | */ | 235 | */ |
254 | { SUB_CHIP_ID1, TWL6030_BASEADD_USB }, | 236 | |
255 | { SUB_CHIP_ID_INVAL, TWL6030_BASEADD_AUDIO }, | 237 | /* Common IPs */ |
256 | { SUB_CHIP_ID2, TWL6030_BASEADD_DIEID }, | 238 | { 1, TWL6030_BASEADD_USB }, |
257 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | 239 | { 1, TWL6030_BASEADD_PIH }, |
258 | { SUB_CHIP_ID1, TWL6030_BASEADD_PIH }, | 240 | { 1, TWL6030_BASEADD_CHARGER }, |
259 | 241 | { 0, TWL6030_BASEADD_PM_MASTER }, | |
260 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | 242 | { 0, TWL6030_BASEADD_PM_SLAVE_MISC }, |
261 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | 243 | |
262 | { SUB_CHIP_ID1, TWL6030_BASEADD_GPADC_CTRL }, | 244 | { 0, TWL6030_BASEADD_RTC }, |
263 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | 245 | { 1, TWL6030_BASEADD_PWM }, |
264 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | 246 | { 1, TWL6030_BASEADD_LED }, |
265 | 247 | { 0, TWL6030_BASEADD_SECURED_REG }, | |
266 | { SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER }, | 248 | |
267 | { SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE }, | 249 | /* TWL6030 specific IPs */ |
268 | { SUB_CHIP_ID1, TWL6030_BASEADD_PWM }, | 250 | { 0, TWL6030_BASEADD_ZERO }, |
269 | { SUB_CHIP_ID0, TWL6030_BASEADD_ZERO }, | 251 | { 1, TWL6030_BASEADD_ZERO }, |
270 | { SUB_CHIP_ID1, TWL6030_BASEADD_ZERO }, | 252 | { 2, TWL6030_BASEADD_ZERO }, |
271 | 253 | { 1, TWL6030_BASEADD_GPADC_CTRL }, | |
272 | { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO }, | 254 | { 1, TWL6030_BASEADD_GASGAUGE }, |
273 | { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO }, | ||
274 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | ||
275 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | ||
276 | { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, | ||
277 | |||
278 | { SUB_CHIP_ID0, TWL6030_BASEADD_PM_MASTER }, | ||
279 | { SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_MISC }, | ||
280 | { SUB_CHIP_ID0, TWL6030_BASEADD_RTC }, | ||
281 | { SUB_CHIP_ID0, TWL6030_BASEADD_MEM }, | ||
282 | { SUB_CHIP_ID1, TWL6025_BASEADD_CHARGER }, | ||
283 | }; | 255 | }; |
284 | 256 | ||
285 | static struct regmap_config twl6030_regmap_config[3] = { | 257 | static struct regmap_config twl6030_regmap_config[3] = { |
@@ -305,8 +277,30 @@ static struct regmap_config twl6030_regmap_config[3] = { | |||
305 | 277 | ||
306 | /*----------------------------------------------------------------------*/ | 278 | /*----------------------------------------------------------------------*/ |
307 | 279 | ||
280 | static inline int twl_get_num_slaves(void) | ||
281 | { | ||
282 | if (twl_class_is_4030()) | ||
283 | return 4; /* TWL4030 class have four slave address */ | ||
284 | else | ||
285 | return 3; /* TWL6030 class have three slave address */ | ||
286 | } | ||
287 | |||
288 | static inline int twl_get_last_module(void) | ||
289 | { | ||
290 | if (twl_class_is_4030()) | ||
291 | return TWL4030_MODULE_LAST; | ||
292 | else | ||
293 | return TWL6030_MODULE_LAST; | ||
294 | } | ||
295 | |||
308 | /* Exported Functions */ | 296 | /* Exported Functions */ |
309 | 297 | ||
298 | unsigned int twl_rev(void) | ||
299 | { | ||
300 | return twl_priv ? twl_priv->twl_id : 0; | ||
301 | } | ||
302 | EXPORT_SYMBOL(twl_rev); | ||
303 | |||
310 | /** | 304 | /** |
311 | * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0 | 305 | * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0 |
312 | * @mod_no: module number | 306 | * @mod_no: module number |
@@ -314,9 +308,6 @@ static struct regmap_config twl6030_regmap_config[3] = { | |||
314 | * @reg: register address (just offset will do) | 308 | * @reg: register address (just offset will do) |
315 | * @num_bytes: number of bytes to transfer | 309 | * @num_bytes: number of bytes to transfer |
316 | * | 310 | * |
317 | * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and | ||
318 | * valid data starts at Offset 1. | ||
319 | * | ||
320 | * Returns the result of operation - 0 is success | 311 | * Returns the result of operation - 0 is success |
321 | */ | 312 | */ |
322 | int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) | 313 | int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) |
@@ -325,24 +316,21 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) | |||
325 | int sid; | 316 | int sid; |
326 | struct twl_client *twl; | 317 | struct twl_client *twl; |
327 | 318 | ||
328 | if (unlikely(mod_no >= TWL_MODULE_LAST)) { | 319 | if (unlikely(mod_no >= twl_get_last_module())) { |
329 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); | 320 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); |
330 | return -EPERM; | 321 | return -EPERM; |
331 | } | 322 | } |
332 | if (unlikely(!inuse)) { | 323 | if (unlikely(!twl_priv->ready)) { |
333 | pr_err("%s: not initialized\n", DRIVER_NAME); | 324 | pr_err("%s: not initialized\n", DRIVER_NAME); |
334 | return -EPERM; | 325 | return -EPERM; |
335 | } | 326 | } |
336 | sid = twl_map[mod_no].sid; | ||
337 | if (unlikely(sid == SUB_CHIP_ID_INVAL)) { | ||
338 | pr_err("%s: module %d is not part of the pmic\n", | ||
339 | DRIVER_NAME, mod_no); | ||
340 | return -EINVAL; | ||
341 | } | ||
342 | twl = &twl_modules[sid]; | ||
343 | 327 | ||
344 | ret = regmap_bulk_write(twl->regmap, twl_map[mod_no].base + reg, | 328 | sid = twl_priv->twl_map[mod_no].sid; |
345 | value, num_bytes); | 329 | twl = &twl_priv->twl_modules[sid]; |
330 | |||
331 | ret = regmap_bulk_write(twl->regmap, | ||
332 | twl_priv->twl_map[mod_no].base + reg, value, | ||
333 | num_bytes); | ||
346 | 334 | ||
347 | if (ret) | 335 | if (ret) |
348 | pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n", | 336 | pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n", |
@@ -367,24 +355,21 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) | |||
367 | int sid; | 355 | int sid; |
368 | struct twl_client *twl; | 356 | struct twl_client *twl; |
369 | 357 | ||
370 | if (unlikely(mod_no >= TWL_MODULE_LAST)) { | 358 | if (unlikely(mod_no >= twl_get_last_module())) { |
371 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); | 359 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); |
372 | return -EPERM; | 360 | return -EPERM; |
373 | } | 361 | } |
374 | if (unlikely(!inuse)) { | 362 | if (unlikely(!twl_priv->ready)) { |
375 | pr_err("%s: not initialized\n", DRIVER_NAME); | 363 | pr_err("%s: not initialized\n", DRIVER_NAME); |
376 | return -EPERM; | 364 | return -EPERM; |
377 | } | 365 | } |
378 | sid = twl_map[mod_no].sid; | ||
379 | if (unlikely(sid == SUB_CHIP_ID_INVAL)) { | ||
380 | pr_err("%s: module %d is not part of the pmic\n", | ||
381 | DRIVER_NAME, mod_no); | ||
382 | return -EINVAL; | ||
383 | } | ||
384 | twl = &twl_modules[sid]; | ||
385 | 366 | ||
386 | ret = regmap_bulk_read(twl->regmap, twl_map[mod_no].base + reg, | 367 | sid = twl_priv->twl_map[mod_no].sid; |
387 | value, num_bytes); | 368 | twl = &twl_priv->twl_modules[sid]; |
369 | |||
370 | ret = regmap_bulk_read(twl->regmap, | ||
371 | twl_priv->twl_map[mod_no].base + reg, value, | ||
372 | num_bytes); | ||
388 | 373 | ||
389 | if (ret) | 374 | if (ret) |
390 | pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n", | 375 | pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n", |
@@ -394,34 +379,6 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) | |||
394 | } | 379 | } |
395 | EXPORT_SYMBOL(twl_i2c_read); | 380 | EXPORT_SYMBOL(twl_i2c_read); |
396 | 381 | ||
397 | /** | ||
398 | * twl_i2c_write_u8 - Writes a 8 bit register in TWL4030/TWL5030/TWL60X0 | ||
399 | * @mod_no: module number | ||
400 | * @value: the value to be written 8 bit | ||
401 | * @reg: register address (just offset will do) | ||
402 | * | ||
403 | * Returns result of operation - 0 is success | ||
404 | */ | ||
405 | int twl_i2c_write_u8(u8 mod_no, u8 value, u8 reg) | ||
406 | { | ||
407 | return twl_i2c_write(mod_no, &value, reg, 1); | ||
408 | } | ||
409 | EXPORT_SYMBOL(twl_i2c_write_u8); | ||
410 | |||
411 | /** | ||
412 | * twl_i2c_read_u8 - Reads a 8 bit register from TWL4030/TWL5030/TWL60X0 | ||
413 | * @mod_no: module number | ||
414 | * @value: the value read 8 bit | ||
415 | * @reg: register address (just offset will do) | ||
416 | * | ||
417 | * Returns result of operation - 0 is success | ||
418 | */ | ||
419 | int twl_i2c_read_u8(u8 mod_no, u8 *value, u8 reg) | ||
420 | { | ||
421 | return twl_i2c_read(mod_no, value, reg, 1); | ||
422 | } | ||
423 | EXPORT_SYMBOL(twl_i2c_read_u8); | ||
424 | |||
425 | /*----------------------------------------------------------------------*/ | 382 | /*----------------------------------------------------------------------*/ |
426 | 383 | ||
427 | /** | 384 | /** |
@@ -440,7 +397,7 @@ static int twl_read_idcode_register(void) | |||
440 | goto fail; | 397 | goto fail; |
441 | } | 398 | } |
442 | 399 | ||
443 | err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode), | 400 | err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_priv->twl_idcode), |
444 | REG_IDCODE_7_0, 4); | 401 | REG_IDCODE_7_0, 4); |
445 | if (err) { | 402 | if (err) { |
446 | pr_err("TWL4030: unable to read IDCODE -%d\n", err); | 403 | pr_err("TWL4030: unable to read IDCODE -%d\n", err); |
@@ -461,7 +418,7 @@ fail: | |||
461 | */ | 418 | */ |
462 | int twl_get_type(void) | 419 | int twl_get_type(void) |
463 | { | 420 | { |
464 | return TWL_SIL_TYPE(twl_idcode); | 421 | return TWL_SIL_TYPE(twl_priv->twl_idcode); |
465 | } | 422 | } |
466 | EXPORT_SYMBOL_GPL(twl_get_type); | 423 | EXPORT_SYMBOL_GPL(twl_get_type); |
467 | 424 | ||
@@ -472,7 +429,7 @@ EXPORT_SYMBOL_GPL(twl_get_type); | |||
472 | */ | 429 | */ |
473 | int twl_get_version(void) | 430 | int twl_get_version(void) |
474 | { | 431 | { |
475 | return TWL_SIL_REV(twl_idcode); | 432 | return TWL_SIL_REV(twl_priv->twl_idcode); |
476 | } | 433 | } |
477 | EXPORT_SYMBOL_GPL(twl_get_version); | 434 | EXPORT_SYMBOL_GPL(twl_get_version); |
478 | 435 | ||
@@ -509,13 +466,20 @@ int twl_get_hfclk_rate(void) | |||
509 | EXPORT_SYMBOL_GPL(twl_get_hfclk_rate); | 466 | EXPORT_SYMBOL_GPL(twl_get_hfclk_rate); |
510 | 467 | ||
511 | static struct device * | 468 | static struct device * |
512 | add_numbered_child(unsigned chip, const char *name, int num, | 469 | add_numbered_child(unsigned mod_no, const char *name, int num, |
513 | void *pdata, unsigned pdata_len, | 470 | void *pdata, unsigned pdata_len, |
514 | bool can_wakeup, int irq0, int irq1) | 471 | bool can_wakeup, int irq0, int irq1) |
515 | { | 472 | { |
516 | struct platform_device *pdev; | 473 | struct platform_device *pdev; |
517 | struct twl_client *twl = &twl_modules[chip]; | 474 | struct twl_client *twl; |
518 | int status; | 475 | int status, sid; |
476 | |||
477 | if (unlikely(mod_no >= twl_get_last_module())) { | ||
478 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); | ||
479 | return ERR_PTR(-EPERM); | ||
480 | } | ||
481 | sid = twl_priv->twl_map[mod_no].sid; | ||
482 | twl = &twl_priv->twl_modules[sid]; | ||
519 | 483 | ||
520 | pdev = platform_device_alloc(name, num); | 484 | pdev = platform_device_alloc(name, num); |
521 | if (!pdev) { | 485 | if (!pdev) { |
@@ -560,11 +524,11 @@ err: | |||
560 | return &pdev->dev; | 524 | return &pdev->dev; |
561 | } | 525 | } |
562 | 526 | ||
563 | static inline struct device *add_child(unsigned chip, const char *name, | 527 | static inline struct device *add_child(unsigned mod_no, const char *name, |
564 | void *pdata, unsigned pdata_len, | 528 | void *pdata, unsigned pdata_len, |
565 | bool can_wakeup, int irq0, int irq1) | 529 | bool can_wakeup, int irq0, int irq1) |
566 | { | 530 | { |
567 | return add_numbered_child(chip, name, -1, pdata, pdata_len, | 531 | return add_numbered_child(mod_no, name, -1, pdata, pdata_len, |
568 | can_wakeup, irq0, irq1); | 532 | can_wakeup, irq0, irq1); |
569 | } | 533 | } |
570 | 534 | ||
@@ -573,7 +537,6 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, | |||
573 | struct regulator_consumer_supply *consumers, | 537 | struct regulator_consumer_supply *consumers, |
574 | unsigned num_consumers, unsigned long features) | 538 | unsigned num_consumers, unsigned long features) |
575 | { | 539 | { |
576 | unsigned sub_chip_id; | ||
577 | struct twl_regulator_driver_data drv_data; | 540 | struct twl_regulator_driver_data drv_data; |
578 | 541 | ||
579 | /* regulator framework demands init_data ... */ | 542 | /* regulator framework demands init_data ... */ |
@@ -600,8 +563,7 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, | |||
600 | } | 563 | } |
601 | 564 | ||
602 | /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ | 565 | /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ |
603 | sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; | 566 | return add_numbered_child(TWL_MODULE_PM_MASTER, "twl_reg", num, |
604 | return add_numbered_child(sub_chip_id, "twl_reg", num, | ||
605 | pdata, sizeof(*pdata), false, 0, 0); | 567 | pdata, sizeof(*pdata), false, 0, 0); |
606 | } | 568 | } |
607 | 569 | ||
@@ -623,10 +585,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
623 | unsigned long features) | 585 | unsigned long features) |
624 | { | 586 | { |
625 | struct device *child; | 587 | struct device *child; |
626 | unsigned sub_chip_id; | ||
627 | 588 | ||
628 | if (IS_ENABLED(CONFIG_GPIO_TWL4030) && pdata->gpio) { | 589 | if (IS_ENABLED(CONFIG_GPIO_TWL4030) && pdata->gpio) { |
629 | child = add_child(SUB_CHIP_ID1, "twl4030_gpio", | 590 | child = add_child(TWL4030_MODULE_GPIO, "twl4030_gpio", |
630 | pdata->gpio, sizeof(*pdata->gpio), | 591 | pdata->gpio, sizeof(*pdata->gpio), |
631 | false, irq_base + GPIO_INTR_OFFSET, 0); | 592 | false, irq_base + GPIO_INTR_OFFSET, 0); |
632 | if (IS_ERR(child)) | 593 | if (IS_ERR(child)) |
@@ -634,7 +595,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
634 | } | 595 | } |
635 | 596 | ||
636 | if (IS_ENABLED(CONFIG_KEYBOARD_TWL4030) && pdata->keypad) { | 597 | if (IS_ENABLED(CONFIG_KEYBOARD_TWL4030) && pdata->keypad) { |
637 | child = add_child(SUB_CHIP_ID2, "twl4030_keypad", | 598 | child = add_child(TWL4030_MODULE_KEYPAD, "twl4030_keypad", |
638 | pdata->keypad, sizeof(*pdata->keypad), | 599 | pdata->keypad, sizeof(*pdata->keypad), |
639 | true, irq_base + KEYPAD_INTR_OFFSET, 0); | 600 | true, irq_base + KEYPAD_INTR_OFFSET, 0); |
640 | if (IS_ERR(child)) | 601 | if (IS_ERR(child)) |
@@ -643,7 +604,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
643 | 604 | ||
644 | if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc && | 605 | if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc && |
645 | twl_class_is_4030()) { | 606 | twl_class_is_4030()) { |
646 | child = add_child(SUB_CHIP_ID2, "twl4030_madc", | 607 | child = add_child(TWL4030_MODULE_MADC, "twl4030_madc", |
647 | pdata->madc, sizeof(*pdata->madc), | 608 | pdata->madc, sizeof(*pdata->madc), |
648 | true, irq_base + MADC_INTR_OFFSET, 0); | 609 | true, irq_base + MADC_INTR_OFFSET, 0); |
649 | if (IS_ERR(child)) | 610 | if (IS_ERR(child)) |
@@ -658,22 +619,21 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
658 | * Eventually, Linux might become more aware of such | 619 | * Eventually, Linux might become more aware of such |
659 | * HW security concerns, and "least privilege". | 620 | * HW security concerns, and "least privilege". |
660 | */ | 621 | */ |
661 | sub_chip_id = twl_map[TWL_MODULE_RTC].sid; | 622 | child = add_child(TWL_MODULE_RTC, "twl_rtc", NULL, 0, |
662 | child = add_child(sub_chip_id, "twl_rtc", NULL, 0, | ||
663 | true, irq_base + RTC_INTR_OFFSET, 0); | 623 | true, irq_base + RTC_INTR_OFFSET, 0); |
664 | if (IS_ERR(child)) | 624 | if (IS_ERR(child)) |
665 | return PTR_ERR(child); | 625 | return PTR_ERR(child); |
666 | } | 626 | } |
667 | 627 | ||
668 | if (IS_ENABLED(CONFIG_PWM_TWL)) { | 628 | if (IS_ENABLED(CONFIG_PWM_TWL)) { |
669 | child = add_child(SUB_CHIP_ID1, "twl-pwm", NULL, 0, | 629 | child = add_child(TWL_MODULE_PWM, "twl-pwm", NULL, 0, |
670 | false, 0, 0); | 630 | false, 0, 0); |
671 | if (IS_ERR(child)) | 631 | if (IS_ERR(child)) |
672 | return PTR_ERR(child); | 632 | return PTR_ERR(child); |
673 | } | 633 | } |
674 | 634 | ||
675 | if (IS_ENABLED(CONFIG_PWM_TWL_LED)) { | 635 | if (IS_ENABLED(CONFIG_PWM_TWL_LED)) { |
676 | child = add_child(SUB_CHIP_ID1, "twl-pwmled", NULL, 0, | 636 | child = add_child(TWL_MODULE_LED, "twl-pwmled", NULL, 0, |
677 | false, 0, 0); | 637 | false, 0, 0); |
678 | if (IS_ERR(child)) | 638 | if (IS_ERR(child)) |
679 | return PTR_ERR(child); | 639 | return PTR_ERR(child); |
@@ -725,7 +685,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
725 | 685 | ||
726 | } | 686 | } |
727 | 687 | ||
728 | child = add_child(SUB_CHIP_ID0, "twl4030_usb", | 688 | child = add_child(TWL_MODULE_USB, "twl4030_usb", |
729 | pdata->usb, sizeof(*pdata->usb), true, | 689 | pdata->usb, sizeof(*pdata->usb), true, |
730 | /* irq0 = USB_PRES, irq1 = USB */ | 690 | /* irq0 = USB_PRES, irq1 = USB */ |
731 | irq_base + USB_PRES_INTR_OFFSET, | 691 | irq_base + USB_PRES_INTR_OFFSET, |
@@ -774,7 +734,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
774 | 734 | ||
775 | pdata->usb->features = features; | 735 | pdata->usb->features = features; |
776 | 736 | ||
777 | child = add_child(SUB_CHIP_ID0, "twl6030_usb", | 737 | child = add_child(TWL_MODULE_USB, "twl6030_usb", |
778 | pdata->usb, sizeof(*pdata->usb), true, | 738 | pdata->usb, sizeof(*pdata->usb), true, |
779 | /* irq1 = VBUS_PRES, irq0 = USB ID */ | 739 | /* irq1 = VBUS_PRES, irq0 = USB ID */ |
780 | irq_base + USBOTG_INTR_OFFSET, | 740 | irq_base + USBOTG_INTR_OFFSET, |
@@ -799,22 +759,22 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
799 | } | 759 | } |
800 | 760 | ||
801 | if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) { | 761 | if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) { |
802 | child = add_child(SUB_CHIP_ID3, "twl4030_wdt", NULL, 0, | 762 | child = add_child(TWL_MODULE_PM_RECEIVER, "twl4030_wdt", NULL, |
803 | false, 0, 0); | 763 | 0, false, 0, 0); |
804 | if (IS_ERR(child)) | 764 | if (IS_ERR(child)) |
805 | return PTR_ERR(child); | 765 | return PTR_ERR(child); |
806 | } | 766 | } |
807 | 767 | ||
808 | if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) { | 768 | if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) { |
809 | child = add_child(SUB_CHIP_ID3, "twl4030_pwrbutton", NULL, 0, | 769 | child = add_child(TWL_MODULE_PM_MASTER, "twl4030_pwrbutton", |
810 | true, irq_base + 8 + 0, 0); | 770 | NULL, 0, true, irq_base + 8 + 0, 0); |
811 | if (IS_ERR(child)) | 771 | if (IS_ERR(child)) |
812 | return PTR_ERR(child); | 772 | return PTR_ERR(child); |
813 | } | 773 | } |
814 | 774 | ||
815 | if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio && | 775 | if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio && |
816 | twl_class_is_4030()) { | 776 | twl_class_is_4030()) { |
817 | child = add_child(SUB_CHIP_ID1, "twl4030-audio", | 777 | child = add_child(TWL4030_MODULE_AUDIO_VOICE, "twl4030-audio", |
818 | pdata->audio, sizeof(*pdata->audio), | 778 | pdata->audio, sizeof(*pdata->audio), |
819 | false, 0, 0); | 779 | false, 0, 0); |
820 | if (IS_ERR(child)) | 780 | if (IS_ERR(child)) |
@@ -1054,7 +1014,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
1054 | 1014 | ||
1055 | if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci && | 1015 | if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci && |
1056 | !(features & (TPS_SUBSET | TWL5031))) { | 1016 | !(features & (TPS_SUBSET | TWL5031))) { |
1057 | child = add_child(SUB_CHIP_ID3, "twl4030_bci", | 1017 | child = add_child(TWL_MODULE_MAIN_CHARGE, "twl4030_bci", |
1058 | pdata->bci, sizeof(*pdata->bci), false, | 1018 | pdata->bci, sizeof(*pdata->bci), false, |
1059 | /* irq0 = CHG_PRES, irq1 = BCI */ | 1019 | /* irq0 = CHG_PRES, irq1 = BCI */ |
1060 | irq_base + BCI_PRES_INTR_OFFSET, | 1020 | irq_base + BCI_PRES_INTR_OFFSET, |
@@ -1145,25 +1105,23 @@ static int twl_remove(struct i2c_client *client) | |||
1145 | unsigned i, num_slaves; | 1105 | unsigned i, num_slaves; |
1146 | int status; | 1106 | int status; |
1147 | 1107 | ||
1148 | if (twl_class_is_4030()) { | 1108 | if (twl_class_is_4030()) |
1149 | status = twl4030_exit_irq(); | 1109 | status = twl4030_exit_irq(); |
1150 | num_slaves = TWL_NUM_SLAVES; | 1110 | else |
1151 | } else { | ||
1152 | status = twl6030_exit_irq(); | 1111 | status = twl6030_exit_irq(); |
1153 | num_slaves = TWL_NUM_SLAVES - 1; | ||
1154 | } | ||
1155 | 1112 | ||
1156 | if (status < 0) | 1113 | if (status < 0) |
1157 | return status; | 1114 | return status; |
1158 | 1115 | ||
1116 | num_slaves = twl_get_num_slaves(); | ||
1159 | for (i = 0; i < num_slaves; i++) { | 1117 | for (i = 0; i < num_slaves; i++) { |
1160 | struct twl_client *twl = &twl_modules[i]; | 1118 | struct twl_client *twl = &twl_priv->twl_modules[i]; |
1161 | 1119 | ||
1162 | if (twl->client && twl->client != client) | 1120 | if (twl->client && twl->client != client) |
1163 | i2c_unregister_device(twl->client); | 1121 | i2c_unregister_device(twl->client); |
1164 | twl_modules[i].client = NULL; | 1122 | twl->client = NULL; |
1165 | } | 1123 | } |
1166 | inuse = false; | 1124 | twl_priv->ready = false; |
1167 | return 0; | 1125 | return 0; |
1168 | } | 1126 | } |
1169 | 1127 | ||
@@ -1179,6 +1137,17 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1179 | int status; | 1137 | int status; |
1180 | unsigned i, num_slaves; | 1138 | unsigned i, num_slaves; |
1181 | 1139 | ||
1140 | if (!node && !pdata) { | ||
1141 | dev_err(&client->dev, "no platform data\n"); | ||
1142 | return -EINVAL; | ||
1143 | } | ||
1144 | |||
1145 | if (twl_priv) { | ||
1146 | dev_dbg(&client->dev, "only one instance of %s allowed\n", | ||
1147 | DRIVER_NAME); | ||
1148 | return -EBUSY; | ||
1149 | } | ||
1150 | |||
1182 | pdev = platform_device_alloc(DRIVER_NAME, -1); | 1151 | pdev = platform_device_alloc(DRIVER_NAME, -1); |
1183 | if (!pdev) { | 1152 | if (!pdev) { |
1184 | dev_err(&client->dev, "can't alloc pdev\n"); | 1153 | dev_err(&client->dev, "can't alloc pdev\n"); |
@@ -1191,54 +1160,44 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1191 | return status; | 1160 | return status; |
1192 | } | 1161 | } |
1193 | 1162 | ||
1194 | if (node && !pdata) { | ||
1195 | /* | ||
1196 | * XXX: Temporary pdata until the information is correctly | ||
1197 | * retrieved by every TWL modules from DT. | ||
1198 | */ | ||
1199 | pdata = devm_kzalloc(&client->dev, | ||
1200 | sizeof(struct twl4030_platform_data), | ||
1201 | GFP_KERNEL); | ||
1202 | if (!pdata) { | ||
1203 | status = -ENOMEM; | ||
1204 | goto free; | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1208 | if (!pdata) { | ||
1209 | dev_dbg(&client->dev, "no platform data?\n"); | ||
1210 | status = -EINVAL; | ||
1211 | goto free; | ||
1212 | } | ||
1213 | |||
1214 | platform_set_drvdata(pdev, pdata); | ||
1215 | |||
1216 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { | 1163 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { |
1217 | dev_dbg(&client->dev, "can't talk I2C?\n"); | 1164 | dev_dbg(&client->dev, "can't talk I2C?\n"); |
1218 | status = -EIO; | 1165 | status = -EIO; |
1219 | goto free; | 1166 | goto free; |
1220 | } | 1167 | } |
1221 | 1168 | ||
1222 | if (inuse) { | 1169 | twl_priv = devm_kzalloc(&client->dev, sizeof(struct twl_private), |
1223 | dev_dbg(&client->dev, "driver is already in use\n"); | 1170 | GFP_KERNEL); |
1224 | status = -EBUSY; | 1171 | if (!twl_priv) { |
1172 | status = -ENOMEM; | ||
1225 | goto free; | 1173 | goto free; |
1226 | } | 1174 | } |
1227 | 1175 | ||
1228 | if ((id->driver_data) & TWL6030_CLASS) { | 1176 | if ((id->driver_data) & TWL6030_CLASS) { |
1229 | twl_id = TWL6030_CLASS_ID; | 1177 | twl_priv->twl_id = TWL6030_CLASS_ID; |
1230 | twl_map = &twl6030_map[0]; | 1178 | twl_priv->twl_map = &twl6030_map[0]; |
1179 | /* The charger base address is different in twl6025 */ | ||
1180 | if ((id->driver_data) & TWL6025_SUBCLASS) | ||
1181 | twl_priv->twl_map[TWL_MODULE_MAIN_CHARGE].base = | ||
1182 | TWL6025_BASEADD_CHARGER; | ||
1231 | twl_regmap_config = twl6030_regmap_config; | 1183 | twl_regmap_config = twl6030_regmap_config; |
1232 | num_slaves = TWL_NUM_SLAVES - 1; | ||
1233 | } else { | 1184 | } else { |
1234 | twl_id = TWL4030_CLASS_ID; | 1185 | twl_priv->twl_id = TWL4030_CLASS_ID; |
1235 | twl_map = &twl4030_map[0]; | 1186 | twl_priv->twl_map = &twl4030_map[0]; |
1236 | twl_regmap_config = twl4030_regmap_config; | 1187 | twl_regmap_config = twl4030_regmap_config; |
1237 | num_slaves = TWL_NUM_SLAVES; | 1188 | } |
1189 | |||
1190 | num_slaves = twl_get_num_slaves(); | ||
1191 | twl_priv->twl_modules = devm_kzalloc(&client->dev, | ||
1192 | sizeof(struct twl_client) * num_slaves, | ||
1193 | GFP_KERNEL); | ||
1194 | if (!twl_priv->twl_modules) { | ||
1195 | status = -ENOMEM; | ||
1196 | goto free; | ||
1238 | } | 1197 | } |
1239 | 1198 | ||
1240 | for (i = 0; i < num_slaves; i++) { | 1199 | for (i = 0; i < num_slaves; i++) { |
1241 | struct twl_client *twl = &twl_modules[i]; | 1200 | struct twl_client *twl = &twl_priv->twl_modules[i]; |
1242 | 1201 | ||
1243 | if (i == 0) { | 1202 | if (i == 0) { |
1244 | twl->client = client; | 1203 | twl->client = client; |
@@ -1264,19 +1223,19 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1264 | } | 1223 | } |
1265 | } | 1224 | } |
1266 | 1225 | ||
1267 | inuse = true; | 1226 | twl_priv->ready = true; |
1268 | 1227 | ||
1269 | /* setup clock framework */ | 1228 | /* setup clock framework */ |
1270 | clocks_init(&pdev->dev, pdata->clock); | 1229 | clocks_init(&pdev->dev, pdata ? pdata->clock : NULL); |
1271 | 1230 | ||
1272 | /* read TWL IDCODE Register */ | 1231 | /* read TWL IDCODE Register */ |
1273 | if (twl_id == TWL4030_CLASS_ID) { | 1232 | if (twl_class_is_4030()) { |
1274 | status = twl_read_idcode_register(); | 1233 | status = twl_read_idcode_register(); |
1275 | WARN(status < 0, "Error: reading twl_idcode register value\n"); | 1234 | WARN(status < 0, "Error: reading twl_idcode register value\n"); |
1276 | } | 1235 | } |
1277 | 1236 | ||
1278 | /* load power event scripts */ | 1237 | /* load power event scripts */ |
1279 | if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata->power) | 1238 | if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata && pdata->power) |
1280 | twl4030_power_init(pdata->power); | 1239 | twl4030_power_init(pdata->power); |
1281 | 1240 | ||
1282 | /* Maybe init the T2 Interrupt subsystem */ | 1241 | /* Maybe init the T2 Interrupt subsystem */ |
@@ -1308,10 +1267,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1308 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); | 1267 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); |
1309 | } | 1268 | } |
1310 | 1269 | ||
1311 | status = -ENODEV; | ||
1312 | if (node) | 1270 | if (node) |
1313 | status = of_platform_populate(node, NULL, NULL, &client->dev); | 1271 | status = of_platform_populate(node, NULL, NULL, &client->dev); |
1314 | if (status) | 1272 | else |
1315 | status = add_children(pdata, irq_base, id->driver_data); | 1273 | status = add_children(pdata, irq_base, id->driver_data); |
1316 | 1274 | ||
1317 | fail: | 1275 | fail: |
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 4dae241e5017..dd362c1078e1 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c | |||
@@ -159,7 +159,7 @@ out: | |||
159 | static int twl4030_write_script(u8 address, struct twl4030_ins *script, | 159 | static int twl4030_write_script(u8 address, struct twl4030_ins *script, |
160 | int len) | 160 | int len) |
161 | { | 161 | { |
162 | int err; | 162 | int err = -EINVAL; |
163 | 163 | ||
164 | for (; len; len--, address++, script++) { | 164 | for (; len; len--, address++, script++) { |
165 | if (len == 1) { | 165 | if (len == 1) { |
diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c index fae15d880758..3c1723aa6225 100644 --- a/drivers/mfd/vexpress-config.c +++ b/drivers/mfd/vexpress-config.c | |||
@@ -67,6 +67,7 @@ struct vexpress_config_bridge *vexpress_config_bridge_register( | |||
67 | 67 | ||
68 | return bridge; | 68 | return bridge; |
69 | } | 69 | } |
70 | EXPORT_SYMBOL(vexpress_config_bridge_register); | ||
70 | 71 | ||
71 | void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge) | 72 | void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge) |
72 | { | 73 | { |
@@ -83,6 +84,7 @@ void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge) | |||
83 | while (!list_empty(&__bridge.transactions)) | 84 | while (!list_empty(&__bridge.transactions)) |
84 | cpu_relax(); | 85 | cpu_relax(); |
85 | } | 86 | } |
87 | EXPORT_SYMBOL(vexpress_config_bridge_unregister); | ||
86 | 88 | ||
87 | 89 | ||
88 | struct vexpress_config_func { | 90 | struct vexpress_config_func { |
@@ -142,6 +144,7 @@ struct vexpress_config_func *__vexpress_config_func_get(struct device *dev, | |||
142 | 144 | ||
143 | return func; | 145 | return func; |
144 | } | 146 | } |
147 | EXPORT_SYMBOL(__vexpress_config_func_get); | ||
145 | 148 | ||
146 | void vexpress_config_func_put(struct vexpress_config_func *func) | 149 | void vexpress_config_func_put(struct vexpress_config_func *func) |
147 | { | 150 | { |
@@ -149,7 +152,7 @@ void vexpress_config_func_put(struct vexpress_config_func *func) | |||
149 | of_node_put(func->bridge->node); | 152 | of_node_put(func->bridge->node); |
150 | kfree(func); | 153 | kfree(func); |
151 | } | 154 | } |
152 | 155 | EXPORT_SYMBOL(vexpress_config_func_put); | |
153 | 156 | ||
154 | struct vexpress_config_trans { | 157 | struct vexpress_config_trans { |
155 | struct vexpress_config_func *func; | 158 | struct vexpress_config_func *func; |
@@ -229,6 +232,7 @@ void vexpress_config_complete(struct vexpress_config_bridge *bridge, | |||
229 | 232 | ||
230 | complete(&trans->completion); | 233 | complete(&trans->completion); |
231 | } | 234 | } |
235 | EXPORT_SYMBOL(vexpress_config_complete); | ||
232 | 236 | ||
233 | int vexpress_config_wait(struct vexpress_config_trans *trans) | 237 | int vexpress_config_wait(struct vexpress_config_trans *trans) |
234 | { | 238 | { |
@@ -236,7 +240,7 @@ int vexpress_config_wait(struct vexpress_config_trans *trans) | |||
236 | 240 | ||
237 | return trans->status; | 241 | return trans->status; |
238 | } | 242 | } |
239 | 243 | EXPORT_SYMBOL(vexpress_config_wait); | |
240 | 244 | ||
241 | int vexpress_config_read(struct vexpress_config_func *func, int offset, | 245 | int vexpress_config_read(struct vexpress_config_func *func, int offset, |
242 | u32 *data) | 246 | u32 *data) |
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index 77048b18439e..a4a43230abcd 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #define SYS_ID_HBI_SHIFT 16 | 49 | #define SYS_ID_HBI_SHIFT 16 |
50 | #define SYS_PROCIDx_HBI_SHIFT 0 | 50 | #define SYS_PROCIDx_HBI_SHIFT 0 |
51 | 51 | ||
52 | #define SYS_LED_LED(n) (1 << (n)) | ||
53 | |||
52 | #define SYS_MCI_CARDIN (1 << 0) | 54 | #define SYS_MCI_CARDIN (1 << 0) |
53 | #define SYS_MCI_WPROT (1 << 1) | 55 | #define SYS_MCI_WPROT (1 << 1) |
54 | 56 | ||
@@ -336,34 +338,40 @@ void __init vexpress_sysreg_early_init(void __iomem *base) | |||
336 | 338 | ||
337 | void __init vexpress_sysreg_of_early_init(void) | 339 | void __init vexpress_sysreg_of_early_init(void) |
338 | { | 340 | { |
339 | struct device_node *node = of_find_compatible_node(NULL, NULL, | 341 | struct device_node *node; |
340 | "arm,vexpress-sysreg"); | 342 | |
343 | if (vexpress_sysreg_base) | ||
344 | return; | ||
341 | 345 | ||
346 | node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); | ||
342 | if (node) { | 347 | if (node) { |
343 | vexpress_sysreg_base = of_iomap(node, 0); | 348 | vexpress_sysreg_base = of_iomap(node, 0); |
344 | vexpress_sysreg_setup(node); | 349 | vexpress_sysreg_setup(node); |
345 | } else { | ||
346 | pr_info("vexpress-sysreg: No Device Tree node found."); | ||
347 | } | 350 | } |
348 | } | 351 | } |
349 | 352 | ||
350 | 353 | ||
354 | #define VEXPRESS_SYSREG_GPIO(_name, _reg, _value) \ | ||
355 | [VEXPRESS_GPIO_##_name] = { \ | ||
356 | .reg = _reg, \ | ||
357 | .value = _reg##_##_value, \ | ||
358 | } | ||
359 | |||
351 | static struct vexpress_sysreg_gpio { | 360 | static struct vexpress_sysreg_gpio { |
352 | unsigned long reg; | 361 | unsigned long reg; |
353 | u32 value; | 362 | u32 value; |
354 | } vexpress_sysreg_gpios[] = { | 363 | } vexpress_sysreg_gpios[] = { |
355 | [VEXPRESS_GPIO_MMC_CARDIN] = { | 364 | VEXPRESS_SYSREG_GPIO(MMC_CARDIN, SYS_MCI, CARDIN), |
356 | .reg = SYS_MCI, | 365 | VEXPRESS_SYSREG_GPIO(MMC_WPROT, SYS_MCI, WPROT), |
357 | .value = SYS_MCI_CARDIN, | 366 | VEXPRESS_SYSREG_GPIO(FLASH_WPn, SYS_FLASH, WPn), |
358 | }, | 367 | VEXPRESS_SYSREG_GPIO(LED0, SYS_LED, LED(0)), |
359 | [VEXPRESS_GPIO_MMC_WPROT] = { | 368 | VEXPRESS_SYSREG_GPIO(LED1, SYS_LED, LED(1)), |
360 | .reg = SYS_MCI, | 369 | VEXPRESS_SYSREG_GPIO(LED2, SYS_LED, LED(2)), |
361 | .value = SYS_MCI_WPROT, | 370 | VEXPRESS_SYSREG_GPIO(LED3, SYS_LED, LED(3)), |
362 | }, | 371 | VEXPRESS_SYSREG_GPIO(LED4, SYS_LED, LED(4)), |
363 | [VEXPRESS_GPIO_FLASH_WPn] = { | 372 | VEXPRESS_SYSREG_GPIO(LED5, SYS_LED, LED(5)), |
364 | .reg = SYS_FLASH, | 373 | VEXPRESS_SYSREG_GPIO(LED6, SYS_LED, LED(6)), |
365 | .value = SYS_FLASH_WPn, | 374 | VEXPRESS_SYSREG_GPIO(LED7, SYS_LED, LED(7)), |
366 | }, | ||
367 | }; | 375 | }; |
368 | 376 | ||
369 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | 377 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, |
@@ -372,12 +380,6 @@ static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | |||
372 | return 0; | 380 | return 0; |
373 | } | 381 | } |
374 | 382 | ||
375 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
376 | unsigned offset, int value) | ||
377 | { | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, | 383 | static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, |
382 | unsigned offset) | 384 | unsigned offset) |
383 | { | 385 | { |
@@ -401,6 +403,14 @@ static void vexpress_sysreg_gpio_set(struct gpio_chip *chip, | |||
401 | writel(reg_value, vexpress_sysreg_base + gpio->reg); | 403 | writel(reg_value, vexpress_sysreg_base + gpio->reg); |
402 | } | 404 | } |
403 | 405 | ||
406 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
407 | unsigned offset, int value) | ||
408 | { | ||
409 | vexpress_sysreg_gpio_set(chip, offset, value); | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
404 | static struct gpio_chip vexpress_sysreg_gpio_chip = { | 414 | static struct gpio_chip vexpress_sysreg_gpio_chip = { |
405 | .label = "vexpress-sysreg", | 415 | .label = "vexpress-sysreg", |
406 | .direction_input = vexpress_sysreg_gpio_direction_input, | 416 | .direction_input = vexpress_sysreg_gpio_direction_input, |
@@ -412,6 +422,30 @@ static struct gpio_chip vexpress_sysreg_gpio_chip = { | |||
412 | }; | 422 | }; |
413 | 423 | ||
414 | 424 | ||
425 | #define VEXPRESS_SYSREG_GREEN_LED(_name, _default_trigger, _gpio) \ | ||
426 | { \ | ||
427 | .name = "v2m:green:"_name, \ | ||
428 | .default_trigger = _default_trigger, \ | ||
429 | .gpio = VEXPRESS_GPIO_##_gpio, \ | ||
430 | } | ||
431 | |||
432 | struct gpio_led vexpress_sysreg_leds[] = { | ||
433 | VEXPRESS_SYSREG_GREEN_LED("user1", "heartbeat", LED0), | ||
434 | VEXPRESS_SYSREG_GREEN_LED("user2", "mmc0", LED1), | ||
435 | VEXPRESS_SYSREG_GREEN_LED("user3", "cpu0", LED2), | ||
436 | VEXPRESS_SYSREG_GREEN_LED("user4", "cpu1", LED3), | ||
437 | VEXPRESS_SYSREG_GREEN_LED("user5", "cpu2", LED4), | ||
438 | VEXPRESS_SYSREG_GREEN_LED("user6", "cpu3", LED5), | ||
439 | VEXPRESS_SYSREG_GREEN_LED("user7", "cpu4", LED6), | ||
440 | VEXPRESS_SYSREG_GREEN_LED("user8", "cpu5", LED7), | ||
441 | }; | ||
442 | |||
443 | struct gpio_led_platform_data vexpress_sysreg_leds_pdata = { | ||
444 | .num_leds = ARRAY_SIZE(vexpress_sysreg_leds), | ||
445 | .leds = vexpress_sysreg_leds, | ||
446 | }; | ||
447 | |||
448 | |||
415 | static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, | 449 | static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, |
416 | struct device_attribute *attr, char *buf) | 450 | struct device_attribute *attr, char *buf) |
417 | { | 451 | { |
@@ -456,6 +490,10 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) | |||
456 | return err; | 490 | return err; |
457 | } | 491 | } |
458 | 492 | ||
493 | platform_device_register_data(vexpress_sysreg_dev, "leds-gpio", | ||
494 | PLATFORM_DEVID_AUTO, &vexpress_sysreg_leds_pdata, | ||
495 | sizeof(vexpress_sysreg_leds_pdata)); | ||
496 | |||
459 | vexpress_sysreg_dev = &pdev->dev; | 497 | vexpress_sysreg_dev = &pdev->dev; |
460 | 498 | ||
461 | device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); | 499 | device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); |
@@ -478,6 +516,7 @@ static struct platform_driver vexpress_sysreg_driver = { | |||
478 | 516 | ||
479 | static int __init vexpress_sysreg_init(void) | 517 | static int __init vexpress_sysreg_init(void) |
480 | { | 518 | { |
519 | vexpress_sysreg_of_early_init(); | ||
481 | return platform_driver_register(&vexpress_sysreg_driver); | 520 | return platform_driver_register(&vexpress_sysreg_driver); |
482 | } | 521 | } |
483 | core_initcall(vexpress_sysreg_init); | 522 | core_initcall(vexpress_sysreg_init); |
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index 088872ab6338..d754596eb942 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
@@ -59,12 +59,13 @@ static const struct reg_default wm5102_reva_patch[] = { | |||
59 | static const struct reg_default wm5102_revb_patch[] = { | 59 | static const struct reg_default wm5102_revb_patch[] = { |
60 | { 0x80, 0x0003 }, | 60 | { 0x80, 0x0003 }, |
61 | { 0x081, 0xE022 }, | 61 | { 0x081, 0xE022 }, |
62 | { 0x410, 0x6080 }, | 62 | { 0x410, 0x4080 }, |
63 | { 0x418, 0x6080 }, | 63 | { 0x418, 0x4080 }, |
64 | { 0x420, 0x6080 }, | 64 | { 0x420, 0x4080 }, |
65 | { 0x428, 0xC000 }, | 65 | { 0x428, 0xC000 }, |
66 | { 0x441, 0x8014 }, | 66 | { 0x4B0, 0x0066 }, |
67 | { 0x458, 0x000b }, | 67 | { 0x458, 0x000b }, |
68 | { 0x212, 0x0000 }, | ||
68 | { 0x80, 0x0000 }, | 69 | { 0x80, 0x0000 }, |
69 | }; | 70 | }; |
70 | 71 | ||
@@ -224,11 +225,9 @@ const struct regmap_irq_chip wm5102_irq = { | |||
224 | static const struct reg_default wm5102_reg_default[] = { | 225 | static const struct reg_default wm5102_reg_default[] = { |
225 | { 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */ | 226 | { 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */ |
226 | { 0x00000009, 0x0001 }, /* R9 - Ctrl IF I2C1 CFG 1 */ | 227 | { 0x00000009, 0x0001 }, /* R9 - Ctrl IF I2C1 CFG 1 */ |
227 | { 0x0000000D, 0x0000 }, /* R13 - Ctrl IF Status 1 */ | ||
228 | { 0x00000016, 0x0000 }, /* R22 - Write Sequencer Ctrl 0 */ | 228 | { 0x00000016, 0x0000 }, /* R22 - Write Sequencer Ctrl 0 */ |
229 | { 0x00000017, 0x0000 }, /* R23 - Write Sequencer Ctrl 1 */ | 229 | { 0x00000017, 0x0000 }, /* R23 - Write Sequencer Ctrl 1 */ |
230 | { 0x00000018, 0x0000 }, /* R24 - Write Sequencer Ctrl 2 */ | 230 | { 0x00000018, 0x0000 }, /* R24 - Write Sequencer Ctrl 2 */ |
231 | { 0x0000001A, 0x0000 }, /* R26 - Write Sequencer PROM */ | ||
232 | { 0x00000020, 0x0000 }, /* R32 - Tone Generator 1 */ | 231 | { 0x00000020, 0x0000 }, /* R32 - Tone Generator 1 */ |
233 | { 0x00000021, 0x1000 }, /* R33 - Tone Generator 2 */ | 232 | { 0x00000021, 0x1000 }, /* R33 - Tone Generator 2 */ |
234 | { 0x00000022, 0x0000 }, /* R34 - Tone Generator 3 */ | 233 | { 0x00000022, 0x0000 }, /* R34 - Tone Generator 3 */ |
@@ -243,12 +242,14 @@ static const struct reg_default wm5102_reg_default[] = { | |||
243 | { 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */ | 242 | { 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */ |
244 | { 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */ | 243 | { 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */ |
245 | { 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */ | 244 | { 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */ |
246 | { 0x00000068, 0x01FF }, /* R104 - Always On Triggers Sequence Select 1 */ | 245 | { 0x00000066, 0x01FF }, /* R102 - Always On Triggers Sequence Select 1 */ |
247 | { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 2 */ | 246 | { 0x00000067, 0x01FF }, /* R103 - Always On Triggers Sequence Select 2 */ |
248 | { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 3 */ | 247 | { 0x00000068, 0x01FF }, /* R104 - Always On Triggers Sequence Select 3 */ |
249 | { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 4 */ | 248 | { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 4 */ |
250 | { 0x0000006C, 0x01FF }, /* R108 - Always On Triggers Sequence Select 5 */ | 249 | { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 5 */ |
251 | { 0x0000006D, 0x01FF }, /* R109 - Always On Triggers Sequence Select 6 */ | 250 | { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 6 */ |
251 | { 0x0000006E, 0x01FF }, /* R110 - Trigger Sequence Select 32 */ | ||
252 | { 0x0000006F, 0x01FF }, /* R111 - Trigger Sequence Select 33 */ | ||
252 | { 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */ | 253 | { 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */ |
253 | { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ | 254 | { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ |
254 | { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ | 255 | { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ |
@@ -258,13 +259,14 @@ static const struct reg_default wm5102_reg_default[] = { | |||
258 | { 0x00000095, 0x0000 }, /* R149 - Haptics phase 2 duration */ | 259 | { 0x00000095, 0x0000 }, /* R149 - Haptics phase 2 duration */ |
259 | { 0x00000096, 0x0000 }, /* R150 - Haptics phase 3 intensity */ | 260 | { 0x00000096, 0x0000 }, /* R150 - Haptics phase 3 intensity */ |
260 | { 0x00000097, 0x0000 }, /* R151 - Haptics phase 3 duration */ | 261 | { 0x00000097, 0x0000 }, /* R151 - Haptics phase 3 duration */ |
261 | { 0x00000100, 0x0001 }, /* R256 - Clock 32k 1 */ | 262 | { 0x00000100, 0x0002 }, /* R256 - Clock 32k 1 */ |
262 | { 0x00000101, 0x0304 }, /* R257 - System Clock 1 */ | 263 | { 0x00000101, 0x0304 }, /* R257 - System Clock 1 */ |
263 | { 0x00000102, 0x0011 }, /* R258 - Sample rate 1 */ | 264 | { 0x00000102, 0x0011 }, /* R258 - Sample rate 1 */ |
264 | { 0x00000103, 0x0011 }, /* R259 - Sample rate 2 */ | 265 | { 0x00000103, 0x0011 }, /* R259 - Sample rate 2 */ |
265 | { 0x00000104, 0x0011 }, /* R260 - Sample rate 3 */ | 266 | { 0x00000104, 0x0011 }, /* R260 - Sample rate 3 */ |
266 | { 0x00000112, 0x0305 }, /* R274 - Async clock 1 */ | 267 | { 0x00000112, 0x0305 }, /* R274 - Async clock 1 */ |
267 | { 0x00000113, 0x0011 }, /* R275 - Async sample rate 1 */ | 268 | { 0x00000113, 0x0011 }, /* R275 - Async sample rate 1 */ |
269 | { 0x00000114, 0x0011 }, /* R276 - Async sample rate 2 */ | ||
268 | { 0x00000149, 0x0000 }, /* R329 - Output system clock */ | 270 | { 0x00000149, 0x0000 }, /* R329 - Output system clock */ |
269 | { 0x0000014A, 0x0000 }, /* R330 - Output async clock */ | 271 | { 0x0000014A, 0x0000 }, /* R330 - Output async clock */ |
270 | { 0x00000152, 0x0000 }, /* R338 - Rate Estimator 1 */ | 272 | { 0x00000152, 0x0000 }, /* R338 - Rate Estimator 1 */ |
@@ -273,13 +275,14 @@ static const struct reg_default wm5102_reg_default[] = { | |||
273 | { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */ | 275 | { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */ |
274 | { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */ | 276 | { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */ |
275 | { 0x00000161, 0x0000 }, /* R353 - Dynamic Frequency Scaling 1 */ | 277 | { 0x00000161, 0x0000 }, /* R353 - Dynamic Frequency Scaling 1 */ |
276 | { 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */ | 278 | { 0x00000171, 0x0002 }, /* R369 - FLL1 Control 1 */ |
277 | { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */ | 279 | { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */ |
278 | { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */ | 280 | { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */ |
279 | { 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */ | 281 | { 0x00000174, 0x007D }, /* R372 - FLL1 Control 4 */ |
280 | { 0x00000175, 0x0004 }, /* R373 - FLL1 Control 5 */ | 282 | { 0x00000175, 0x0004 }, /* R373 - FLL1 Control 5 */ |
281 | { 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */ | 283 | { 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */ |
282 | { 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */ | 284 | { 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */ |
285 | { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */ | ||
283 | { 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */ | 286 | { 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */ |
284 | { 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */ | 287 | { 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */ |
285 | { 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */ | 288 | { 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */ |
@@ -295,6 +298,7 @@ static const struct reg_default wm5102_reg_default[] = { | |||
295 | { 0x00000195, 0x0004 }, /* R405 - FLL2 Control 5 */ | 298 | { 0x00000195, 0x0004 }, /* R405 - FLL2 Control 5 */ |
296 | { 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */ | 299 | { 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */ |
297 | { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */ | 300 | { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */ |
301 | { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */ | ||
298 | { 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */ | 302 | { 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */ |
299 | { 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */ | 303 | { 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */ |
300 | { 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */ | 304 | { 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */ |
@@ -310,8 +314,13 @@ static const struct reg_default wm5102_reg_default[] = { | |||
310 | { 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */ | 314 | { 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */ |
311 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ | 315 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ |
312 | { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ | 316 | { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ |
317 | { 0x00000225, 0x0400 }, /* R549 - HP Ctrl 1L */ | ||
318 | { 0x00000226, 0x0400 }, /* R550 - HP Ctrl 1R */ | ||
313 | { 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */ | 319 | { 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */ |
314 | { 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */ | 320 | { 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */ |
321 | { 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */ | ||
322 | { 0x0000029F, 0x0000 }, /* R671 - Headphone Detect Test */ | ||
323 | { 0x000002A2, 0x0000 }, /* R674 - Micd Clamp control */ | ||
315 | { 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */ | 324 | { 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */ |
316 | { 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */ | 325 | { 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */ |
317 | { 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */ | 326 | { 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */ |
@@ -342,53 +351,44 @@ static const struct reg_default wm5102_reg_default[] = { | |||
342 | { 0x00000400, 0x0000 }, /* R1024 - Output Enables 1 */ | 351 | { 0x00000400, 0x0000 }, /* R1024 - Output Enables 1 */ |
343 | { 0x00000408, 0x0000 }, /* R1032 - Output Rate 1 */ | 352 | { 0x00000408, 0x0000 }, /* R1032 - Output Rate 1 */ |
344 | { 0x00000409, 0x0022 }, /* R1033 - Output Volume Ramp */ | 353 | { 0x00000409, 0x0022 }, /* R1033 - Output Volume Ramp */ |
345 | { 0x00000410, 0x0080 }, /* R1040 - Output Path Config 1L */ | 354 | { 0x00000410, 0x4080 }, /* R1040 - Output Path Config 1L */ |
346 | { 0x00000411, 0x0180 }, /* R1041 - DAC Digital Volume 1L */ | 355 | { 0x00000411, 0x0180 }, /* R1041 - DAC Digital Volume 1L */ |
347 | { 0x00000412, 0x0080 }, /* R1042 - DAC Volume Limit 1L */ | 356 | { 0x00000412, 0x0081 }, /* R1042 - DAC Volume Limit 1L */ |
348 | { 0x00000413, 0x0001 }, /* R1043 - Noise Gate Select 1L */ | 357 | { 0x00000413, 0x0001 }, /* R1043 - Noise Gate Select 1L */ |
349 | { 0x00000414, 0x0080 }, /* R1044 - Output Path Config 1R */ | 358 | { 0x00000414, 0x0080 }, /* R1044 - Output Path Config 1R */ |
350 | { 0x00000415, 0x0180 }, /* R1045 - DAC Digital Volume 1R */ | 359 | { 0x00000415, 0x0180 }, /* R1045 - DAC Digital Volume 1R */ |
351 | { 0x00000416, 0x0080 }, /* R1046 - DAC Volume Limit 1R */ | 360 | { 0x00000416, 0x0081 }, /* R1046 - DAC Volume Limit 1R */ |
352 | { 0x00000417, 0x0002 }, /* R1047 - Noise Gate Select 1R */ | 361 | { 0x00000417, 0x0002 }, /* R1047 - Noise Gate Select 1R */ |
353 | { 0x00000418, 0x0080 }, /* R1048 - Output Path Config 2L */ | 362 | { 0x00000418, 0x4080 }, /* R1048 - Output Path Config 2L */ |
354 | { 0x00000419, 0x0180 }, /* R1049 - DAC Digital Volume 2L */ | 363 | { 0x00000419, 0x0180 }, /* R1049 - DAC Digital Volume 2L */ |
355 | { 0x0000041A, 0x0080 }, /* R1050 - DAC Volume Limit 2L */ | 364 | { 0x0000041A, 0x0081 }, /* R1050 - DAC Volume Limit 2L */ |
356 | { 0x0000041B, 0x0004 }, /* R1051 - Noise Gate Select 2L */ | 365 | { 0x0000041B, 0x0004 }, /* R1051 - Noise Gate Select 2L */ |
357 | { 0x0000041C, 0x0080 }, /* R1052 - Output Path Config 2R */ | 366 | { 0x0000041C, 0x0080 }, /* R1052 - Output Path Config 2R */ |
358 | { 0x0000041D, 0x0180 }, /* R1053 - DAC Digital Volume 2R */ | 367 | { 0x0000041D, 0x0180 }, /* R1053 - DAC Digital Volume 2R */ |
359 | { 0x0000041E, 0x0080 }, /* R1054 - DAC Volume Limit 2R */ | 368 | { 0x0000041E, 0x0081 }, /* R1054 - DAC Volume Limit 2R */ |
360 | { 0x0000041F, 0x0008 }, /* R1055 - Noise Gate Select 2R */ | 369 | { 0x0000041F, 0x0008 }, /* R1055 - Noise Gate Select 2R */ |
361 | { 0x00000420, 0x0080 }, /* R1056 - Output Path Config 3L */ | 370 | { 0x00000420, 0x4080 }, /* R1056 - Output Path Config 3L */ |
362 | { 0x00000421, 0x0180 }, /* R1057 - DAC Digital Volume 3L */ | 371 | { 0x00000421, 0x0180 }, /* R1057 - DAC Digital Volume 3L */ |
363 | { 0x00000422, 0x0080 }, /* R1058 - DAC Volume Limit 3L */ | 372 | { 0x00000422, 0x0081 }, /* R1058 - DAC Volume Limit 3L */ |
364 | { 0x00000423, 0x0010 }, /* R1059 - Noise Gate Select 3L */ | 373 | { 0x00000423, 0x0010 }, /* R1059 - Noise Gate Select 3L */ |
365 | { 0x00000424, 0x0080 }, /* R1060 - Output Path Config 3R */ | 374 | { 0x00000428, 0xC000 }, /* R1064 - Output Path Config 4L */ |
366 | { 0x00000425, 0x0180 }, /* R1061 - DAC Digital Volume 3R */ | ||
367 | { 0x00000426, 0x0080 }, /* R1062 - DAC Volume Limit 3R */ | ||
368 | { 0x00000428, 0x0000 }, /* R1064 - Output Path Config 4L */ | ||
369 | { 0x00000429, 0x0180 }, /* R1065 - DAC Digital Volume 4L */ | 375 | { 0x00000429, 0x0180 }, /* R1065 - DAC Digital Volume 4L */ |
370 | { 0x0000042A, 0x0080 }, /* R1066 - Out Volume 4L */ | 376 | { 0x0000042A, 0x0081 }, /* R1066 - Out Volume 4L */ |
371 | { 0x0000042B, 0x0040 }, /* R1067 - Noise Gate Select 4L */ | 377 | { 0x0000042B, 0x0040 }, /* R1067 - Noise Gate Select 4L */ |
372 | { 0x0000042C, 0x0000 }, /* R1068 - Output Path Config 4R */ | ||
373 | { 0x0000042D, 0x0180 }, /* R1069 - DAC Digital Volume 4R */ | 378 | { 0x0000042D, 0x0180 }, /* R1069 - DAC Digital Volume 4R */ |
374 | { 0x0000042E, 0x0080 }, /* R1070 - Out Volume 4R */ | 379 | { 0x0000042E, 0x0081 }, /* R1070 - Out Volume 4R */ |
375 | { 0x0000042F, 0x0080 }, /* R1071 - Noise Gate Select 4R */ | 380 | { 0x0000042F, 0x0080 }, /* R1071 - Noise Gate Select 4R */ |
376 | { 0x00000430, 0x0000 }, /* R1072 - Output Path Config 5L */ | 381 | { 0x00000430, 0x0000 }, /* R1072 - Output Path Config 5L */ |
377 | { 0x00000431, 0x0180 }, /* R1073 - DAC Digital Volume 5L */ | 382 | { 0x00000431, 0x0180 }, /* R1073 - DAC Digital Volume 5L */ |
378 | { 0x00000432, 0x0080 }, /* R1074 - DAC Volume Limit 5L */ | 383 | { 0x00000432, 0x0081 }, /* R1074 - DAC Volume Limit 5L */ |
379 | { 0x00000433, 0x0100 }, /* R1075 - Noise Gate Select 5L */ | 384 | { 0x00000433, 0x0100 }, /* R1075 - Noise Gate Select 5L */ |
380 | { 0x00000434, 0x0000 }, /* R1076 - Output Path Config 5R */ | ||
381 | { 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */ | 385 | { 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */ |
382 | { 0x00000436, 0x0080 }, /* R1078 - DAC Volume Limit 5R */ | 386 | { 0x00000436, 0x0081 }, /* R1078 - DAC Volume Limit 5R */ |
383 | { 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */ | 387 | { 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */ |
384 | { 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */ | 388 | { 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */ |
385 | { 0x00000458, 0x0001 }, /* R1112 - Noise Gate Control */ | 389 | { 0x00000458, 0x0001 }, /* R1112 - Noise Gate Control */ |
386 | { 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */ | 390 | { 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */ |
387 | { 0x00000491, 0x0000 }, /* R1169 - PDM SPK1 CTRL 2 */ | 391 | { 0x00000491, 0x0000 }, /* R1169 - PDM SPK1 CTRL 2 */ |
388 | { 0x000004DC, 0x0000 }, /* R1244 - DAC comp 1 */ | ||
389 | { 0x000004DD, 0x0000 }, /* R1245 - DAC comp 2 */ | ||
390 | { 0x000004DE, 0x0000 }, /* R1246 - DAC comp 3 */ | ||
391 | { 0x000004DF, 0x0000 }, /* R1247 - DAC comp 4 */ | ||
392 | { 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */ | 392 | { 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */ |
393 | { 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */ | 393 | { 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */ |
394 | { 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */ | 394 | { 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */ |
@@ -416,7 +416,6 @@ static const struct reg_default wm5102_reg_default[] = { | |||
416 | { 0x00000518, 0x0007 }, /* R1304 - AIF1 Frame Ctrl 18 */ | 416 | { 0x00000518, 0x0007 }, /* R1304 - AIF1 Frame Ctrl 18 */ |
417 | { 0x00000519, 0x0000 }, /* R1305 - AIF1 Tx Enables */ | 417 | { 0x00000519, 0x0000 }, /* R1305 - AIF1 Tx Enables */ |
418 | { 0x0000051A, 0x0000 }, /* R1306 - AIF1 Rx Enables */ | 418 | { 0x0000051A, 0x0000 }, /* R1306 - AIF1 Rx Enables */ |
419 | { 0x0000051B, 0x0000 }, /* R1307 - AIF1 Force Write */ | ||
420 | { 0x00000540, 0x000C }, /* R1344 - AIF2 BCLK Ctrl */ | 419 | { 0x00000540, 0x000C }, /* R1344 - AIF2 BCLK Ctrl */ |
421 | { 0x00000541, 0x0008 }, /* R1345 - AIF2 Tx Pin Ctrl */ | 420 | { 0x00000541, 0x0008 }, /* R1345 - AIF2 Tx Pin Ctrl */ |
422 | { 0x00000542, 0x0000 }, /* R1346 - AIF2 Rx Pin Ctrl */ | 421 | { 0x00000542, 0x0000 }, /* R1346 - AIF2 Rx Pin Ctrl */ |
@@ -432,7 +431,6 @@ static const struct reg_default wm5102_reg_default[] = { | |||
432 | { 0x00000552, 0x0001 }, /* R1362 - AIF2 Frame Ctrl 12 */ | 431 | { 0x00000552, 0x0001 }, /* R1362 - AIF2 Frame Ctrl 12 */ |
433 | { 0x00000559, 0x0000 }, /* R1369 - AIF2 Tx Enables */ | 432 | { 0x00000559, 0x0000 }, /* R1369 - AIF2 Tx Enables */ |
434 | { 0x0000055A, 0x0000 }, /* R1370 - AIF2 Rx Enables */ | 433 | { 0x0000055A, 0x0000 }, /* R1370 - AIF2 Rx Enables */ |
435 | { 0x0000055B, 0x0000 }, /* R1371 - AIF2 Force Write */ | ||
436 | { 0x00000580, 0x000C }, /* R1408 - AIF3 BCLK Ctrl */ | 434 | { 0x00000580, 0x000C }, /* R1408 - AIF3 BCLK Ctrl */ |
437 | { 0x00000581, 0x0008 }, /* R1409 - AIF3 Tx Pin Ctrl */ | 435 | { 0x00000581, 0x0008 }, /* R1409 - AIF3 Tx Pin Ctrl */ |
438 | { 0x00000582, 0x0000 }, /* R1410 - AIF3 Rx Pin Ctrl */ | 436 | { 0x00000582, 0x0000 }, /* R1410 - AIF3 Rx Pin Ctrl */ |
@@ -448,7 +446,6 @@ static const struct reg_default wm5102_reg_default[] = { | |||
448 | { 0x00000592, 0x0001 }, /* R1426 - AIF3 Frame Ctrl 12 */ | 446 | { 0x00000592, 0x0001 }, /* R1426 - AIF3 Frame Ctrl 12 */ |
449 | { 0x00000599, 0x0000 }, /* R1433 - AIF3 Tx Enables */ | 447 | { 0x00000599, 0x0000 }, /* R1433 - AIF3 Tx Enables */ |
450 | { 0x0000059A, 0x0000 }, /* R1434 - AIF3 Rx Enables */ | 448 | { 0x0000059A, 0x0000 }, /* R1434 - AIF3 Rx Enables */ |
451 | { 0x0000059B, 0x0000 }, /* R1435 - AIF3 Force Write */ | ||
452 | { 0x000005E3, 0x0004 }, /* R1507 - SLIMbus Framer Ref Gear */ | 449 | { 0x000005E3, 0x0004 }, /* R1507 - SLIMbus Framer Ref Gear */ |
453 | { 0x000005E5, 0x0000 }, /* R1509 - SLIMbus Rates 1 */ | 450 | { 0x000005E5, 0x0000 }, /* R1509 - SLIMbus Rates 1 */ |
454 | { 0x000005E6, 0x0000 }, /* R1510 - SLIMbus Rates 2 */ | 451 | { 0x000005E6, 0x0000 }, /* R1510 - SLIMbus Rates 2 */ |
@@ -772,22 +769,6 @@ static const struct reg_default wm5102_reg_default[] = { | |||
772 | { 0x000008CD, 0x0080 }, /* R2253 - DRC1RMIX Input 3 Volume */ | 769 | { 0x000008CD, 0x0080 }, /* R2253 - DRC1RMIX Input 3 Volume */ |
773 | { 0x000008CE, 0x0000 }, /* R2254 - DRC1RMIX Input 4 Source */ | 770 | { 0x000008CE, 0x0000 }, /* R2254 - DRC1RMIX Input 4 Source */ |
774 | { 0x000008CF, 0x0080 }, /* R2255 - DRC1RMIX Input 4 Volume */ | 771 | { 0x000008CF, 0x0080 }, /* R2255 - DRC1RMIX Input 4 Volume */ |
775 | { 0x000008D0, 0x0000 }, /* R2256 - DRC2LMIX Input 1 Source */ | ||
776 | { 0x000008D1, 0x0080 }, /* R2257 - DRC2LMIX Input 1 Volume */ | ||
777 | { 0x000008D2, 0x0000 }, /* R2258 - DRC2LMIX Input 2 Source */ | ||
778 | { 0x000008D3, 0x0080 }, /* R2259 - DRC2LMIX Input 2 Volume */ | ||
779 | { 0x000008D4, 0x0000 }, /* R2260 - DRC2LMIX Input 3 Source */ | ||
780 | { 0x000008D5, 0x0080 }, /* R2261 - DRC2LMIX Input 3 Volume */ | ||
781 | { 0x000008D6, 0x0000 }, /* R2262 - DRC2LMIX Input 4 Source */ | ||
782 | { 0x000008D7, 0x0080 }, /* R2263 - DRC2LMIX Input 4 Volume */ | ||
783 | { 0x000008D8, 0x0000 }, /* R2264 - DRC2RMIX Input 1 Source */ | ||
784 | { 0x000008D9, 0x0080 }, /* R2265 - DRC2RMIX Input 1 Volume */ | ||
785 | { 0x000008DA, 0x0000 }, /* R2266 - DRC2RMIX Input 2 Source */ | ||
786 | { 0x000008DB, 0x0080 }, /* R2267 - DRC2RMIX Input 2 Volume */ | ||
787 | { 0x000008DC, 0x0000 }, /* R2268 - DRC2RMIX Input 3 Source */ | ||
788 | { 0x000008DD, 0x0080 }, /* R2269 - DRC2RMIX Input 3 Volume */ | ||
789 | { 0x000008DE, 0x0000 }, /* R2270 - DRC2RMIX Input 4 Source */ | ||
790 | { 0x000008DF, 0x0080 }, /* R2271 - DRC2RMIX Input 4 Volume */ | ||
791 | { 0x00000900, 0x0000 }, /* R2304 - HPLP1MIX Input 1 Source */ | 772 | { 0x00000900, 0x0000 }, /* R2304 - HPLP1MIX Input 1 Source */ |
792 | { 0x00000901, 0x0080 }, /* R2305 - HPLP1MIX Input 1 Volume */ | 773 | { 0x00000901, 0x0080 }, /* R2305 - HPLP1MIX Input 1 Volume */ |
793 | { 0x00000902, 0x0000 }, /* R2306 - HPLP1MIX Input 2 Source */ | 774 | { 0x00000902, 0x0000 }, /* R2306 - HPLP1MIX Input 2 Source */ |
@@ -879,7 +860,7 @@ static const struct reg_default wm5102_reg_default[] = { | |||
879 | { 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */ | 860 | { 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */ |
880 | { 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */ | 861 | { 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */ |
881 | { 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */ | 862 | { 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */ |
882 | { 0x00000D41, 0x0000 }, /* R3393 - ADSP2 IRQ0 */ | 863 | { 0x00000D50, 0x0000 }, /* R3408 - AOD wkup and trig */ |
883 | { 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */ | 864 | { 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */ |
884 | { 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */ | 865 | { 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */ |
885 | { 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */ | 866 | { 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */ |
@@ -974,11 +955,6 @@ static const struct reg_default wm5102_reg_default[] = { | |||
974 | { 0x00000E82, 0x0018 }, /* R3714 - DRC1 ctrl3 */ | 955 | { 0x00000E82, 0x0018 }, /* R3714 - DRC1 ctrl3 */ |
975 | { 0x00000E83, 0x0000 }, /* R3715 - DRC1 ctrl4 */ | 956 | { 0x00000E83, 0x0000 }, /* R3715 - DRC1 ctrl4 */ |
976 | { 0x00000E84, 0x0000 }, /* R3716 - DRC1 ctrl5 */ | 957 | { 0x00000E84, 0x0000 }, /* R3716 - DRC1 ctrl5 */ |
977 | { 0x00000E89, 0x0018 }, /* R3721 - DRC2 ctrl1 */ | ||
978 | { 0x00000E8A, 0x0933 }, /* R3722 - DRC2 ctrl2 */ | ||
979 | { 0x00000E8B, 0x0018 }, /* R3723 - DRC2 ctrl3 */ | ||
980 | { 0x00000E8C, 0x0000 }, /* R3724 - DRC2 ctrl4 */ | ||
981 | { 0x00000E8D, 0x0000 }, /* R3725 - DRC2 ctrl5 */ | ||
982 | { 0x00000EC0, 0x0000 }, /* R3776 - HPLPF1_1 */ | 958 | { 0x00000EC0, 0x0000 }, /* R3776 - HPLPF1_1 */ |
983 | { 0x00000EC1, 0x0000 }, /* R3777 - HPLPF1_2 */ | 959 | { 0x00000EC1, 0x0000 }, /* R3777 - HPLPF1_2 */ |
984 | { 0x00000EC4, 0x0000 }, /* R3780 - HPLPF2_1 */ | 960 | { 0x00000EC4, 0x0000 }, /* R3780 - HPLPF2_1 */ |
@@ -989,16 +965,12 @@ static const struct reg_default wm5102_reg_default[] = { | |||
989 | { 0x00000ECD, 0x0000 }, /* R3789 - HPLPF4_2 */ | 965 | { 0x00000ECD, 0x0000 }, /* R3789 - HPLPF4_2 */ |
990 | { 0x00000EE0, 0x0000 }, /* R3808 - ASRC_ENABLE */ | 966 | { 0x00000EE0, 0x0000 }, /* R3808 - ASRC_ENABLE */ |
991 | { 0x00000EE2, 0x0000 }, /* R3810 - ASRC_RATE1 */ | 967 | { 0x00000EE2, 0x0000 }, /* R3810 - ASRC_RATE1 */ |
992 | { 0x00000EE3, 0x4000 }, /* R3811 - ASRC_RATE2 */ | ||
993 | { 0x00000EF0, 0x0000 }, /* R3824 - ISRC 1 CTRL 1 */ | 968 | { 0x00000EF0, 0x0000 }, /* R3824 - ISRC 1 CTRL 1 */ |
994 | { 0x00000EF1, 0x0000 }, /* R3825 - ISRC 1 CTRL 2 */ | 969 | { 0x00000EF1, 0x0000 }, /* R3825 - ISRC 1 CTRL 2 */ |
995 | { 0x00000EF2, 0x0000 }, /* R3826 - ISRC 1 CTRL 3 */ | 970 | { 0x00000EF2, 0x0000 }, /* R3826 - ISRC 1 CTRL 3 */ |
996 | { 0x00000EF3, 0x0000 }, /* R3827 - ISRC 2 CTRL 1 */ | 971 | { 0x00000EF3, 0x0000 }, /* R3827 - ISRC 2 CTRL 1 */ |
997 | { 0x00000EF4, 0x0000 }, /* R3828 - ISRC 2 CTRL 2 */ | 972 | { 0x00000EF4, 0x0000 }, /* R3828 - ISRC 2 CTRL 2 */ |
998 | { 0x00000EF5, 0x0000 }, /* R3829 - ISRC 2 CTRL 3 */ | 973 | { 0x00000EF5, 0x0000 }, /* R3829 - ISRC 2 CTRL 3 */ |
999 | { 0x00000EF6, 0x0000 }, /* R3830 - ISRC 3 CTRL 1 */ | ||
1000 | { 0x00000EF7, 0x0000 }, /* R3831 - ISRC 3 CTRL 2 */ | ||
1001 | { 0x00000EF8, 0x0000 }, /* R3832 - ISRC 3 CTRL 3 */ | ||
1002 | { 0x00001100, 0x0010 }, /* R4352 - DSP1 Control 1 */ | 974 | { 0x00001100, 0x0010 }, /* R4352 - DSP1 Control 1 */ |
1003 | { 0x00001101, 0x0000 }, /* R4353 - DSP1 Clocking 1 */ | 975 | { 0x00001101, 0x0000 }, /* R4353 - DSP1 Clocking 1 */ |
1004 | }; | 976 | }; |
@@ -1823,17 +1795,24 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
1823 | case ARIZONA_DSP1_STATUS_1: | 1795 | case ARIZONA_DSP1_STATUS_1: |
1824 | case ARIZONA_DSP1_STATUS_2: | 1796 | case ARIZONA_DSP1_STATUS_2: |
1825 | case ARIZONA_DSP1_STATUS_3: | 1797 | case ARIZONA_DSP1_STATUS_3: |
1798 | case ARIZONA_DSP1_SCRATCH_0: | ||
1799 | case ARIZONA_DSP1_SCRATCH_1: | ||
1800 | case ARIZONA_DSP1_SCRATCH_2: | ||
1801 | case ARIZONA_DSP1_SCRATCH_3: | ||
1826 | return true; | 1802 | return true; |
1827 | default: | 1803 | default: |
1828 | return false; | 1804 | if ((reg >= 0x100000 && reg < 0x106000) || |
1805 | (reg >= 0x180000 && reg < 0x180800) || | ||
1806 | (reg >= 0x190000 && reg < 0x194800) || | ||
1807 | (reg >= 0x1a8000 && reg < 0x1a9800)) | ||
1808 | return true; | ||
1809 | else | ||
1810 | return false; | ||
1829 | } | 1811 | } |
1830 | } | 1812 | } |
1831 | 1813 | ||
1832 | static bool wm5102_volatile_register(struct device *dev, unsigned int reg) | 1814 | static bool wm5102_volatile_register(struct device *dev, unsigned int reg) |
1833 | { | 1815 | { |
1834 | if (reg > 0xffff) | ||
1835 | return true; | ||
1836 | |||
1837 | switch (reg) { | 1816 | switch (reg) { |
1838 | case ARIZONA_SOFTWARE_RESET: | 1817 | case ARIZONA_SOFTWARE_RESET: |
1839 | case ARIZONA_DEVICE_REVISION: | 1818 | case ARIZONA_DEVICE_REVISION: |
@@ -1874,15 +1853,25 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg) | |||
1874 | case ARIZONA_DSP1_STATUS_1: | 1853 | case ARIZONA_DSP1_STATUS_1: |
1875 | case ARIZONA_DSP1_STATUS_2: | 1854 | case ARIZONA_DSP1_STATUS_2: |
1876 | case ARIZONA_DSP1_STATUS_3: | 1855 | case ARIZONA_DSP1_STATUS_3: |
1856 | case ARIZONA_DSP1_SCRATCH_0: | ||
1857 | case ARIZONA_DSP1_SCRATCH_1: | ||
1858 | case ARIZONA_DSP1_SCRATCH_2: | ||
1859 | case ARIZONA_DSP1_SCRATCH_3: | ||
1877 | case ARIZONA_HEADPHONE_DETECT_2: | 1860 | case ARIZONA_HEADPHONE_DETECT_2: |
1878 | case ARIZONA_MIC_DETECT_3: | 1861 | case ARIZONA_MIC_DETECT_3: |
1879 | return true; | 1862 | return true; |
1880 | default: | 1863 | default: |
1881 | return false; | 1864 | if ((reg >= 0x100000 && reg < 0x106000) || |
1865 | (reg >= 0x180000 && reg < 0x180800) || | ||
1866 | (reg >= 0x190000 && reg < 0x194800) || | ||
1867 | (reg >= 0x1a8000 && reg < 0x1a9800)) | ||
1868 | return true; | ||
1869 | else | ||
1870 | return false; | ||
1882 | } | 1871 | } |
1883 | } | 1872 | } |
1884 | 1873 | ||
1885 | #define WM5102_MAX_REGISTER 0x1a8fff | 1874 | #define WM5102_MAX_REGISTER 0x1a9800 |
1886 | 1875 | ||
1887 | const struct regmap_config wm5102_spi_regmap = { | 1876 | const struct regmap_config wm5102_spi_regmap = { |
1888 | .reg_bits = 32, | 1877 | .reg_bits = 32, |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 57c488d42d3e..803e93fae56a 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -467,7 +467,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
467 | goto err; | 467 | goto err; |
468 | } | 468 | } |
469 | 469 | ||
470 | ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, | 470 | ret = devm_regulator_bulk_get(wm8994->dev, wm8994->num_supplies, |
471 | wm8994->supplies); | 471 | wm8994->supplies); |
472 | if (ret != 0) { | 472 | if (ret != 0) { |
473 | dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); | 473 | dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); |
@@ -478,7 +478,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
478 | wm8994->supplies); | 478 | wm8994->supplies); |
479 | if (ret != 0) { | 479 | if (ret != 0) { |
480 | dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); | 480 | dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); |
481 | goto err_get; | 481 | goto err; |
482 | } | 482 | } |
483 | 483 | ||
484 | ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET); | 484 | ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET); |
@@ -658,8 +658,6 @@ err_irq: | |||
658 | err_enable: | 658 | err_enable: |
659 | regulator_bulk_disable(wm8994->num_supplies, | 659 | regulator_bulk_disable(wm8994->num_supplies, |
660 | wm8994->supplies); | 660 | wm8994->supplies); |
661 | err_get: | ||
662 | regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); | ||
663 | err: | 661 | err: |
664 | mfd_remove_devices(wm8994->dev); | 662 | mfd_remove_devices(wm8994->dev); |
665 | return ret; | 663 | return ret; |
@@ -672,7 +670,6 @@ static void wm8994_device_exit(struct wm8994 *wm8994) | |||
672 | wm8994_irq_exit(wm8994); | 670 | wm8994_irq_exit(wm8994); |
673 | regulator_bulk_disable(wm8994->num_supplies, | 671 | regulator_bulk_disable(wm8994->num_supplies, |
674 | wm8994->supplies); | 672 | wm8994->supplies); |
675 | regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); | ||
676 | } | 673 | } |
677 | 674 | ||
678 | static const struct of_device_id wm8994_of_match[] = { | 675 | static const struct of_device_id wm8994_of_match[] = { |