675 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * wm8994-core.c -- Device access for Wolfson WM89944 *5 * Copyright 2009 Wolfson Microelectronics PLC.6 *7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/slab.h>13#include <linux/i2c.h>14#include <linux/err.h>15#include <linux/delay.h>16#include <linux/mfd/core.h>17#include <linux/of.h>18#include <linux/pm_runtime.h>19#include <linux/regmap.h>20#include <linux/regulator/consumer.h>21#include <linux/regulator/machine.h>22 23#include <linux/mfd/wm8994/core.h>24#include <linux/mfd/wm8994/pdata.h>25#include <linux/mfd/wm8994/registers.h>26 27#include "wm8994.h"28 29static const struct mfd_cell wm8994_regulator_devs[] = {30 {31 .name = "wm8994-ldo",32 .id = 0,33 .pm_runtime_no_callbacks = true,34 },35 {36 .name = "wm8994-ldo",37 .id = 1,38 .pm_runtime_no_callbacks = true,39 },40};41 42static const struct resource wm8994_codec_resources[] = {43 {44 .start = WM8994_IRQ_TEMP_SHUT,45 .end = WM8994_IRQ_TEMP_WARN,46 .flags = IORESOURCE_IRQ,47 },48};49 50static const struct resource wm8994_gpio_resources[] = {51 {52 .start = WM8994_IRQ_GPIO(1),53 .end = WM8994_IRQ_GPIO(11),54 .flags = IORESOURCE_IRQ,55 },56};57 58static const struct mfd_cell wm8994_devs[] = {59 {60 .name = "wm8994-codec",61 .num_resources = ARRAY_SIZE(wm8994_codec_resources),62 .resources = wm8994_codec_resources,63 },64 65 {66 .name = "wm8994-gpio",67 .num_resources = ARRAY_SIZE(wm8994_gpio_resources),68 .resources = wm8994_gpio_resources,69 .pm_runtime_no_callbacks = true,70 },71};72 73/*74 * Supplies for the main bulk of CODEC; the LDO supplies are ignored75 * and should be handled via the standard regulator API supply76 * management.77 */78static const char *wm1811_main_supplies[] = {79 "DBVDD1",80 "DBVDD2",81 "DBVDD3",82 "DCVDD",83 "AVDD1",84 "AVDD2",85 "CPVDD",86 "SPKVDD1",87 "SPKVDD2",88};89 90static const char *wm8994_main_supplies[] = {91 "DBVDD",92 "DCVDD",93 "AVDD1",94 "AVDD2",95 "CPVDD",96 "SPKVDD1",97 "SPKVDD2",98};99 100static const char *wm8958_main_supplies[] = {101 "DBVDD1",102 "DBVDD2",103 "DBVDD3",104 "DCVDD",105 "AVDD1",106 "AVDD2",107 "CPVDD",108 "SPKVDD1",109 "SPKVDD2",110};111 112static int wm8994_suspend(struct device *dev)113{114 struct wm8994 *wm8994 = dev_get_drvdata(dev);115 int ret;116 117 /* Don't actually go through with the suspend if the CODEC is118 * still active for accessory detect. */119 switch (wm8994->type) {120 case WM8958:121 case WM1811:122 ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);123 if (ret < 0) {124 dev_err(dev, "Failed to read power status: %d\n", ret);125 } else if (ret & WM8958_MICD_ENA) {126 dev_dbg(dev, "CODEC still active, ignoring suspend\n");127 return 0;128 }129 break;130 default:131 break;132 }133 134 /* Disable LDO pulldowns while the device is suspended if we135 * don't know that something will be driving them. */136 if (!wm8994->ldo_ena_always_driven)137 wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,138 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,139 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);140 141 /* Explicitly put the device into reset in case regulators142 * don't get disabled in order to ensure consistent restart.143 */144 wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,145 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));146 147 regcache_mark_dirty(wm8994->regmap);148 149 /* Restore GPIO registers to prevent problems with mismatched150 * pin configurations.151 */152 ret = regcache_sync_region(wm8994->regmap, WM8994_GPIO_1,153 WM8994_GPIO_11);154 if (ret != 0)155 dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);156 157 /* In case one of the GPIOs is used as a wake input. */158 ret = regcache_sync_region(wm8994->regmap,159 WM8994_INTERRUPT_STATUS_1_MASK,160 WM8994_INTERRUPT_STATUS_1_MASK);161 if (ret != 0)162 dev_err(dev, "Failed to restore interrupt mask: %d\n", ret);163 164 regcache_cache_only(wm8994->regmap, true);165 wm8994->suspended = true;166 167 ret = regulator_bulk_disable(wm8994->num_supplies,168 wm8994->supplies);169 if (ret != 0) {170 dev_err(dev, "Failed to disable supplies: %d\n", ret);171 return ret;172 }173 174 return 0;175}176 177static int wm8994_resume(struct device *dev)178{179 struct wm8994 *wm8994 = dev_get_drvdata(dev);180 int ret;181 182 /* We may have lied to the PM core about suspending */183 if (!wm8994->suspended)184 return 0;185 186 ret = regulator_bulk_enable(wm8994->num_supplies,187 wm8994->supplies);188 if (ret != 0) {189 dev_err(dev, "Failed to enable supplies: %d\n", ret);190 return ret;191 }192 193 regcache_cache_only(wm8994->regmap, false);194 ret = regcache_sync(wm8994->regmap);195 if (ret != 0) {196 dev_err(dev, "Failed to restore register map: %d\n", ret);197 goto err_enable;198 }199 200 /* Disable LDO pulldowns while the device is active */201 wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,202 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,203 0);204 205 wm8994->suspended = false;206 207 return 0;208 209err_enable:210 regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);211 212 return ret;213}214 215#ifdef CONFIG_REGULATOR216static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)217{218 struct wm8994_ldo_pdata *ldo_pdata;219 220 if (!pdata)221 return 0;222 223 ldo_pdata = &pdata->ldo[ldo];224 225 if (!ldo_pdata->init_data)226 return 0;227 228 return ldo_pdata->init_data->num_consumer_supplies != 0;229}230#else231static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)232{233 return 0;234}235#endif236 237static const struct reg_sequence wm8994_revc_patch[] = {238 { 0x102, 0x3 },239 { 0x56, 0x3 },240 { 0x817, 0x0 },241 { 0x102, 0x0 },242};243 244static const struct reg_sequence wm8958_reva_patch[] = {245 { 0x102, 0x3 },246 { 0xcb, 0x81 },247 { 0x817, 0x0 },248 { 0x102, 0x0 },249};250 251static const struct reg_sequence wm1811_reva_patch[] = {252 { 0x102, 0x3 },253 { 0x56, 0xc07 },254 { 0x5d, 0x7e },255 { 0x5e, 0x0 },256 { 0x102, 0x0 },257};258 259#ifdef CONFIG_OF260static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)261{262 struct device_node *np = wm8994->dev->of_node;263 struct wm8994_pdata *pdata = &wm8994->pdata;264 int i;265 266 if (!np)267 return 0;268 269 if (of_property_read_u32_array(np, "wlf,gpio-cfg", pdata->gpio_defaults,270 ARRAY_SIZE(pdata->gpio_defaults)) >= 0) {271 for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {272 if (wm8994->pdata.gpio_defaults[i] == 0)273 pdata->gpio_defaults[i]274 = WM8994_CONFIGURE_GPIO;275 }276 }277 278 of_property_read_u32_array(np, "wlf,micbias-cfg", pdata->micbias,279 ARRAY_SIZE(pdata->micbias));280 281 pdata->lineout1_diff = !of_property_read_bool(np, "wlf,lineout1-se");282 pdata->lineout2_diff = !of_property_read_bool(np, "wlf,lineout2-se");283 pdata->lineout1fb = of_property_read_bool(np, "wlf,lineout1-feedback");284 pdata->lineout2fb = of_property_read_bool(np, "wlf,lineout2-feedback") ||285 of_property_read_bool(np, "wlf,ldoena-always-driven");286 287 pdata->spkmode_pu = of_property_read_bool(np, "wlf,spkmode-pu");288 289 pdata->csnaddr_pd = of_property_read_bool(np, "wlf,csnaddr-pd");290 291 return 0;292}293#else294static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)295{296 return 0;297}298#endif299 300/*301 * Instantiate the generic non-control parts of the device.302 */303static int wm8994_device_init(struct wm8994 *wm8994, int irq)304{305 struct wm8994_pdata *pdata;306 struct regmap_config *regmap_config;307 const struct reg_sequence *regmap_patch = NULL;308 const char *devname;309 int ret, i, patch_regs = 0;310 int pulls = 0;311 312 if (dev_get_platdata(wm8994->dev)) {313 pdata = dev_get_platdata(wm8994->dev);314 wm8994->pdata = *pdata;315 }316 pdata = &wm8994->pdata;317 318 ret = wm8994_set_pdata_from_of(wm8994);319 if (ret != 0)320 return ret;321 322 /* Add the on-chip regulators first for bootstrapping */323 ret = mfd_add_devices(wm8994->dev, 0,324 wm8994_regulator_devs,325 ARRAY_SIZE(wm8994_regulator_devs),326 NULL, 0, NULL);327 if (ret != 0) {328 dev_err(wm8994->dev, "Failed to add children: %d\n", ret);329 goto err;330 }331 332 switch (wm8994->type) {333 case WM1811:334 wm8994->num_supplies = ARRAY_SIZE(wm1811_main_supplies);335 break;336 case WM8994:337 wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);338 break;339 case WM8958:340 wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies);341 break;342 default:343 BUG();344 goto err;345 }346 347 wm8994->supplies = devm_kcalloc(wm8994->dev,348 wm8994->num_supplies,349 sizeof(struct regulator_bulk_data),350 GFP_KERNEL);351 if (!wm8994->supplies) {352 ret = -ENOMEM;353 goto err;354 }355 356 switch (wm8994->type) {357 case WM1811:358 for (i = 0; i < ARRAY_SIZE(wm1811_main_supplies); i++)359 wm8994->supplies[i].supply = wm1811_main_supplies[i];360 break;361 case WM8994:362 for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)363 wm8994->supplies[i].supply = wm8994_main_supplies[i];364 break;365 case WM8958:366 for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++)367 wm8994->supplies[i].supply = wm8958_main_supplies[i];368 break;369 default:370 BUG();371 goto err;372 }373 374 /*375 * Can't use devres helper here as some of the supplies are provided by376 * wm8994->dev's children (regulators) and those regulators are377 * unregistered by the devres core before the supplies are freed.378 */379 ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,380 wm8994->supplies);381 if (ret != 0) {382 if (ret != -EPROBE_DEFER)383 dev_err(wm8994->dev, "Failed to get supplies: %d\n",384 ret);385 goto err;386 }387 388 ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies);389 if (ret != 0) {390 dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);391 goto err_regulator_free;392 }393 394 ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET);395 if (ret < 0) {396 dev_err(wm8994->dev, "Failed to read ID register\n");397 goto err_enable;398 }399 switch (ret) {400 case 0x1811:401 devname = "WM1811";402 if (wm8994->type != WM1811)403 dev_warn(wm8994->dev, "Device registered as type %d\n",404 wm8994->type);405 wm8994->type = WM1811;406 break;407 case 0x8994:408 devname = "WM8994";409 if (wm8994->type != WM8994)410 dev_warn(wm8994->dev, "Device registered as type %d\n",411 wm8994->type);412 wm8994->type = WM8994;413 break;414 case 0x8958:415 devname = "WM8958";416 if (wm8994->type != WM8958)417 dev_warn(wm8994->dev, "Device registered as type %d\n",418 wm8994->type);419 wm8994->type = WM8958;420 break;421 default:422 dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",423 ret);424 ret = -EINVAL;425 goto err_enable;426 }427 428 ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION);429 if (ret < 0) {430 dev_err(wm8994->dev, "Failed to read revision register: %d\n",431 ret);432 goto err_enable;433 }434 wm8994->revision = ret & WM8994_CHIP_REV_MASK;435 wm8994->cust_id = (ret & WM8994_CUST_ID_MASK) >> WM8994_CUST_ID_SHIFT;436 437 switch (wm8994->type) {438 case WM8994:439 switch (wm8994->revision) {440 case 0:441 case 1:442 dev_warn(wm8994->dev,443 "revision %c not fully supported\n",444 'A' + wm8994->revision);445 break;446 case 2:447 case 3:448 default:449 regmap_patch = wm8994_revc_patch;450 patch_regs = ARRAY_SIZE(wm8994_revc_patch);451 break;452 }453 break;454 455 case WM8958:456 switch (wm8994->revision) {457 case 0:458 regmap_patch = wm8958_reva_patch;459 patch_regs = ARRAY_SIZE(wm8958_reva_patch);460 break;461 default:462 break;463 }464 break;465 466 case WM1811:467 /* Revision C did not change the relevant layer */468 if (wm8994->revision > 1)469 wm8994->revision++;470 471 regmap_patch = wm1811_reva_patch;472 patch_regs = ARRAY_SIZE(wm1811_reva_patch);473 break;474 475 default:476 break;477 }478 479 dev_info(wm8994->dev, "%s revision %c CUST_ID %02x\n", devname,480 'A' + wm8994->revision, wm8994->cust_id);481 482 switch (wm8994->type) {483 case WM1811:484 regmap_config = &wm1811_regmap_config;485 break;486 case WM8994:487 regmap_config = &wm8994_regmap_config;488 break;489 case WM8958:490 regmap_config = &wm8958_regmap_config;491 break;492 default:493 dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type);494 ret = -EINVAL;495 goto err_enable;496 }497 498 ret = regmap_reinit_cache(wm8994->regmap, regmap_config);499 if (ret != 0) {500 dev_err(wm8994->dev, "Failed to reinit register cache: %d\n",501 ret);502 goto err_enable;503 }504 505 /* Explicitly put the device into reset in case regulators506 * don't get disabled in order to ensure we know the device507 * state.508 */509 ret = wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,510 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));511 if (ret != 0) {512 dev_err(wm8994->dev, "Failed to reset device: %d\n", ret);513 goto err_enable;514 }515 516 if (regmap_patch) {517 ret = regmap_register_patch(wm8994->regmap, regmap_patch,518 patch_regs);519 if (ret != 0) {520 dev_err(wm8994->dev, "Failed to register patch: %d\n",521 ret);522 goto err_enable;523 }524 }525 526 wm8994->irq_base = pdata->irq_base;527 wm8994->gpio_base = pdata->gpio_base;528 529 /* GPIO configuration is only applied if it's non-zero */530 for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {531 if (pdata->gpio_defaults[i]) {532 wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,533 0xffff, pdata->gpio_defaults[i]);534 }535 }536 537 wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;538 539 if (pdata->spkmode_pu)540 pulls |= WM8994_SPKMODE_PU;541 if (pdata->csnaddr_pd)542 pulls |= WM8994_CSNADDR_PD;543 544 /* Disable unneeded pulls */545 wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,546 WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD |547 WM8994_SPKMODE_PU | WM8994_CSNADDR_PD,548 pulls);549 550 /* In some system designs where the regulators are not in use,551 * we can achieve a small reduction in leakage currents by552 * floating LDO outputs. This bit makes no difference if the553 * LDOs are enabled, it only affects cases where the LDOs were554 * in operation and are then disabled.555 */556 for (i = 0; i < WM8994_NUM_LDO_REGS; i++) {557 if (wm8994_ldo_in_use(pdata, i))558 wm8994_set_bits(wm8994, WM8994_LDO_1 + i,559 WM8994_LDO1_DISCH, WM8994_LDO1_DISCH);560 else561 wm8994_set_bits(wm8994, WM8994_LDO_1 + i,562 WM8994_LDO1_DISCH, 0);563 }564 565 wm8994_irq_init(wm8994);566 567 ret = mfd_add_devices(wm8994->dev, -1,568 wm8994_devs, ARRAY_SIZE(wm8994_devs),569 NULL, 0, NULL);570 if (ret != 0) {571 dev_err(wm8994->dev, "Failed to add children: %d\n", ret);572 goto err_irq;573 }574 575 pm_runtime_set_active(wm8994->dev);576 pm_runtime_enable(wm8994->dev);577 pm_runtime_idle(wm8994->dev);578 579 return 0;580 581err_irq:582 wm8994_irq_exit(wm8994);583err_enable:584 regulator_bulk_disable(wm8994->num_supplies,585 wm8994->supplies);586err_regulator_free:587 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);588err:589 mfd_remove_devices(wm8994->dev);590 return ret;591}592 593static void wm8994_device_exit(struct wm8994 *wm8994)594{595 pm_runtime_get_sync(wm8994->dev);596 pm_runtime_disable(wm8994->dev);597 pm_runtime_put_noidle(wm8994->dev);598 wm8994_irq_exit(wm8994);599 regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);600 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);601 mfd_remove_devices(wm8994->dev);602}603 604static const struct of_device_id wm8994_of_match[] = {605 { .compatible = "wlf,wm1811", .data = (void *)WM1811 },606 { .compatible = "wlf,wm8994", .data = (void *)WM8994 },607 { .compatible = "wlf,wm8958", .data = (void *)WM8958 },608 { }609};610MODULE_DEVICE_TABLE(of, wm8994_of_match);611 612static int wm8994_i2c_probe(struct i2c_client *i2c)613{614 struct wm8994 *wm8994;615 int ret;616 617 wm8994 = devm_kzalloc(&i2c->dev, sizeof(struct wm8994), GFP_KERNEL);618 if (wm8994 == NULL)619 return -ENOMEM;620 621 i2c_set_clientdata(i2c, wm8994);622 wm8994->dev = &i2c->dev;623 wm8994->irq = i2c->irq;624 625 wm8994->type = (kernel_ulong_t)i2c_get_match_data(i2c);626 627 wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config);628 if (IS_ERR(wm8994->regmap)) {629 ret = PTR_ERR(wm8994->regmap);630 dev_err(wm8994->dev, "Failed to allocate register map: %d\n",631 ret);632 return ret;633 }634 635 return wm8994_device_init(wm8994, i2c->irq);636}637 638static void wm8994_i2c_remove(struct i2c_client *i2c)639{640 struct wm8994 *wm8994 = i2c_get_clientdata(i2c);641 642 wm8994_device_exit(wm8994);643}644 645static const struct i2c_device_id wm8994_i2c_id[] = {646 { "wm1811", WM1811 },647 { "wm1811a", WM1811 },648 { "wm8994", WM8994 },649 { "wm8958", WM8958 },650 { }651};652MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);653 654static const struct dev_pm_ops wm8994_pm_ops = {655 RUNTIME_PM_OPS(wm8994_suspend, wm8994_resume, NULL)656};657 658static struct i2c_driver wm8994_i2c_driver = {659 .driver = {660 .name = "wm8994",661 .pm = pm_ptr(&wm8994_pm_ops),662 .of_match_table = wm8994_of_match,663 },664 .probe = wm8994_i2c_probe,665 .remove = wm8994_i2c_remove,666 .id_table = wm8994_i2c_id,667};668 669module_i2c_driver(wm8994_i2c_driver);670 671MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC");672MODULE_LICENSE("GPL");673MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");674MODULE_SOFTDEP("pre: wm8994_regulator");675