static int aic31xx_codec_probe(struct snd_soc_codec *codec) { int ret = 0; struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); int i; dev_dbg(aic31xx->dev, "## %s\n", __func__); aic31xx = snd_soc_codec_get_drvdata(codec); aic31xx->codec = codec; for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) { aic31xx->disable_nb[i].nb.notifier_call = aic31xx_regulator_event; aic31xx->disable_nb[i].aic31xx = aic31xx; ret = regulator_register_notifier(aic31xx->supplies[i].consumer, &aic31xx->disable_nb[i].nb); if (ret) { dev_err(codec->dev, "Failed to request regulator notifier: %d\n", ret); return ret; } } regcache_cache_only(aic31xx->regmap, true); regcache_mark_dirty(aic31xx->regmap); ret = aic31xx_add_controls(codec); if (ret) return ret; ret = aic31xx_add_widgets(codec); return ret; }
static int wm8994_resume(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; /* We may have lied to the PM core about suspending */ if (!wm8994->suspended) return 0; ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to enable supplies: %d\n", ret); return ret; } regcache_cache_only(wm8994->regmap, false); ret = regcache_sync(wm8994->regmap); if (ret != 0) { dev_err(dev, "Failed to restore register map: %d\n", ret); goto err_enable; } /* Disable LDO pulldowns while the device is active */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, 0); wm8994->suspended = false; return 0; err_enable: regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); return ret; }
static int cs42l73_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec); switch (level) { case SND_SOC_BIAS_ON: snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 0); snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 0); break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { regcache_cache_only(cs42l73->regmap, false); regcache_sync(cs42l73->regmap); } snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1); break; case SND_SOC_BIAS_OFF: snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1); if (cs42l73->shutdwn_delay > 0) { mdelay(cs42l73->shutdwn_delay); cs42l73->shutdwn_delay = 0; } else { mdelay(15); /* Min amount of time requred to power * down. */ } snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1); break; } return 0; }
static int pcm512x_resume(struct device *dev) { struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); int ret; if (!IS_ERR(pcm512x->sclk)) { ret = clk_prepare_enable(pcm512x->sclk); if (ret != 0) { dev_err(dev, "Failed to enable SCLK: %d\n", ret); return ret; } } ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); if (ret != 0) { dev_err(dev, "Failed to enable supplies: %d\n", ret); return ret; } regcache_cache_only(pcm512x->regmap, false); ret = regcache_sync(pcm512x->regmap); if (ret != 0) { dev_err(dev, "Failed to sync cache: %d\n", ret); return ret; } ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, PCM512x_RQPD, 0); if (ret != 0) { dev_err(dev, "Failed to remove power down: %d\n", ret); return ret; } return 0; }
static int wm8994_suspend(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; /* Don't actually go through with the suspend if the CODEC is * still active for accessory detect. */ switch (wm8994->type) { case WM8958: case WM1811: ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & WM8958_MICD_ENA) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } break; default: break; } /* Disable LDO pulldowns while the device is suspended if we * don't know that something will be driving them. */ if (!wm8994->ldo_ena_always_driven) wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD); /* Explicitly put the device into reset in case regulators * don't get disabled in order to ensure consistent restart. */ wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET)); regcache_mark_dirty(wm8994->regmap); /* Restore GPIO registers to prevent problems with mismatched * pin configurations. */ ret = regcache_sync_region(wm8994->regmap, WM8994_GPIO_1, WM8994_GPIO_11); if (ret != 0) dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); /* In case one of the GPIOs is used as a wake input. */ ret = regcache_sync_region(wm8994->regmap, WM8994_INTERRUPT_STATUS_1_MASK, WM8994_INTERRUPT_STATUS_1_MASK); if (ret != 0) dev_err(dev, "Failed to restore interrupt mask: %d\n", ret); regcache_cache_only(wm8994->regmap, true); wm8994->suspended = true; ret = regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to disable supplies: %d\n", ret); return ret; } return 0; }
static int tegra30_dam_probe(struct platform_device *pdev) { struct resource *res, *region; struct tegra30_dam_context *dam; int ret = 0; int clkm_rate; u32 val32; if (pdev->dev.of_node) { of_property_read_u32(pdev->dev.of_node, "nvidia,ahub-dam-id", &val32); pdev->id = (int)val32; } if ((pdev->id < 0) || (pdev->id >= TEGRA30_NR_DAM_IFC)) { dev_err(&pdev->dev, "ID %d out of range\n", pdev->id); return -EINVAL; } dams_cont_info[pdev->id] = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_dam_context), GFP_KERNEL); if (!dams_cont_info[pdev->id]) { dev_err(&pdev->dev, "Can't allocate dam context\n"); ret = -ENOMEM; goto exit; } dams_cont_info[pdev->id]->dev = &pdev->dev; dam = dams_cont_info[pdev->id]; dev_set_drvdata(&pdev->dev, dam); dam->dam_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dam->dam_clk)) { dev_err(&pdev->dev, "Can't retrieve dam clock\n"); ret = PTR_ERR(dam->dam_clk); goto err_free; } clkm_rate = clk_get_rate(clk_get_parent(dam->dam_clk)); while (clkm_rate > 13000000) clkm_rate >>= 1; clk_set_rate(dam->dam_clk,clkm_rate); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "No memory 0 resource\n"); ret = -ENODEV; goto err_clk_put_dam; } region = devm_request_mem_region(&pdev->dev, res->start, resource_size(res), pdev->name); if (!region) { dev_err(&pdev->dev, "Memory region 0 already claimed\n"); ret = -EBUSY; goto err_clk_put_dam; } dam->damregs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!dam->damregs) { dev_err(&pdev->dev, "ioremap 0 failed\n"); ret = -ENOMEM; goto err_clk_put_dam; } dam->regmap = devm_regmap_init_mmio(&pdev->dev, dam->damregs, &tegra30_dam_regmap_config); if (IS_ERR(dam->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); ret = PTR_ERR(dam->regmap); goto err_clk_put_dam; } regcache_cache_only(dam->regmap, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra30_dam_runtime_resume(&pdev->dev); if (ret) goto err_pm_disable; } tegra30_dam_debug_add(dam, pdev->id); return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); err_clk_put_dam: clk_put(dam->dam_clk); err_free: dams_cont_info[pdev->id] = NULL; exit: return ret; }
static int cs35l32_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { struct cs35l32_private *cs35l32; struct device_node *np = i2c_client->dev.of_node; u32 val32; int ret; unsigned int devid = 0; unsigned int reg; cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l32_private), GFP_KERNEL); if (!cs35l32) { dev_err(&i2c_client->dev, "could not allocate codec\n"); return -ENOMEM; } i2c_set_clientdata(i2c_client, cs35l32); cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap); if (IS_ERR(cs35l32->regmap)) { ret = PTR_ERR(cs35l32->regmap); dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); return ret; } if (of_property_read_u32(np, "cs35l32,boost-mng", &val32) >= 0) cs35l32->pdata.boost_mng = val32; if (of_property_read_u32(np, "cs35l32,sdout-datacfg", &val32) >= 0) cs35l32->pdata.sdout_datacfg = val32; if (of_property_read_u32(np, "cs35l32,sdout-share", &val32) >= 0) cs35l32->pdata.sdout_share = val32; cs35l32->pdata.gpio_nreset = of_get_named_gpio_flags(np, "cs35l32,gpio-nreset", 0, NULL); ret = gpio_request(cs35l32->pdata.gpio_nreset, "cs35l32 reset"); if (ret < 0) { dev_err(&i2c_client->dev, "failed to request the gpio %d\n", cs35l32->pdata.gpio_nreset); return ret; } /*bring the chip out of reset*/ gpio_direction_output(cs35l32->pdata.gpio_nreset, 0); msleep(20); gpio_set_value_cansleep(cs35l32->pdata.gpio_nreset, 1); msleep(20); ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch, ARRAY_SIZE(cs35l32_monitor_patch)); if (ret < 0) { dev_err(&i2c_client->dev, "failed to register regmap(try again : 0x40)\n"); i2c_client->addr = 0x40; ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch, ARRAY_SIZE(cs35l32_monitor_patch)); if (ret < 0) dev_err(&i2c_client->dev, "failed to register regmap retry again\n"); } /* initialize codec */ ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, ®); devid = (reg & 0xFF) << 12; ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, ®); devid |= (reg & 0xFF) << 4; ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, ®); devid |= (reg & 0xF0) >> 4; if ((devid != CS35L32_CHIP_ID) && (devid != CS35L32_CHIP_ID_VZW)) { ret = -ENODEV; dev_err(&i2c_client->dev, "CS35L32 Device ID (%X). Expected %X\n", devid, CS35L32_CHIP_ID); return ret; } ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, ®); if (ret < 0) { dev_err(&i2c_client->dev, "Get Revision ID failed\n"); return ret;; } dev_info(&i2c_client->dev, "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF); regcache_cache_only(cs35l32->regmap, false); ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_cs35l32, cs35l32_dai, ARRAY_SIZE(cs35l32_dai)); if (ret < 0) return ret; return 0; }
static int max98925_resume(struct device *dev) { regcache_cache_only(max98925_data->regmapL, false); return regcache_sync(max98925_data->regmapL); }
static int cs35l33_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { struct cs35l33_private *cs35l33; struct cs35l33_pdata *pdata = dev_get_platdata(&i2c_client->dev); int ret, devid, i; unsigned int reg; cs35l33 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l33_private), GFP_KERNEL); if (!cs35l33) return -ENOMEM; i2c_set_clientdata(i2c_client, cs35l33); cs35l33->regmap = devm_regmap_init_i2c(i2c_client, &cs35l33_regmap); if (IS_ERR(cs35l33->regmap)) { ret = PTR_ERR(cs35l33->regmap); dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); return ret; } regcache_cache_only(cs35l33->regmap, true); for (i = 0; i < ARRAY_SIZE(cs35l33_core_supplies); i++) cs35l33->core_supplies[i].supply = cs35l33_core_supplies[i]; cs35l33->num_core_supplies = ARRAY_SIZE(cs35l33_core_supplies); ret = devm_regulator_bulk_get(&i2c_client->dev, cs35l33->num_core_supplies, cs35l33->core_supplies); if (ret != 0) { dev_err(&i2c_client->dev, "Failed to request core supplies: %d\n", ret); return ret; } if (pdata) { cs35l33->pdata = *pdata; } else { cs35l33_of_get_pdata(&i2c_client->dev, cs35l33); pdata = &cs35l33->pdata; } ret = devm_request_threaded_irq(&i2c_client->dev, i2c_client->irq, NULL, cs35l33_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW, "cs35l33", cs35l33); if (ret != 0) dev_warn(&i2c_client->dev, "Failed to request IRQ: %d\n", ret); /* We could issue !RST or skip it based on AMP topology */ cs35l33->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, "reset-gpios", GPIOD_OUT_HIGH); if (IS_ERR(cs35l33->reset_gpio)) { dev_err(&i2c_client->dev, "%s ERROR: Can't get reset GPIO\n", __func__); return PTR_ERR(cs35l33->reset_gpio); } ret = regulator_bulk_enable(cs35l33->num_core_supplies, cs35l33->core_supplies); if (ret != 0) { dev_err(&i2c_client->dev, "Failed to enable core supplies: %d\n", ret); return ret; } gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); msleep(CS35L33_BOOT_DELAY); regcache_cache_only(cs35l33->regmap, false); /* initialize codec */ ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_AB, ®); devid = (reg & 0xFF) << 12; ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_CD, ®); devid |= (reg & 0xFF) << 4; ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_E, ®); devid |= (reg & 0xF0) >> 4; if (devid != CS35L33_CHIP_ID) { dev_err(&i2c_client->dev, "CS35L33 Device ID (%X). Expected ID %X\n", devid, CS35L33_CHIP_ID); goto err_enable; } ret = regmap_read(cs35l33->regmap, CS35L33_REV_ID, ®); if (ret < 0) { dev_err(&i2c_client->dev, "Get Revision ID failed\n"); goto err_enable; } dev_info(&i2c_client->dev, "Cirrus Logic CS35L33, Revision: %02X\n", reg & 0xFF); ret = regmap_register_patch(cs35l33->regmap, cs35l33_patch, ARRAY_SIZE(cs35l33_patch)); if (ret < 0) { dev_err(&i2c_client->dev, "Error in applying regmap patch: %d\n", ret); goto err_enable; } /* disable mclk and tdm */ regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL, CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM, CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM); pm_runtime_set_autosuspend_delay(&i2c_client->dev, 100); pm_runtime_use_autosuspend(&i2c_client->dev); pm_runtime_set_active(&i2c_client->dev); pm_runtime_enable(&i2c_client->dev); ret = devm_snd_soc_register_component(&i2c_client->dev, &soc_component_dev_cs35l33, &cs35l33_dai, 1); if (ret < 0) { dev_err(&i2c_client->dev, "%s: Register component failed\n", __func__); goto err_enable; } return 0; err_enable: regulator_bulk_disable(cs35l33->num_core_supplies, cs35l33->core_supplies); return ret; }
int arizona_dev_init(struct arizona *arizona) { struct device *dev = arizona->dev; const char *type_name; unsigned int reg, val; int (*apply_patch)(struct arizona *) = NULL; int ret, i; dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock); if (dev_get_platdata(arizona->dev)) memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), sizeof(arizona->pdata)); else arizona_of_get_core_pdata(arizona); regcache_cache_only(arizona->regmap, true); switch (arizona->type) { case WM5102: case WM5110: case WM8997: for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) arizona->core_supplies[i].supply = wm5102_core_supplies[i]; arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies); break; default: dev_err(arizona->dev, "Unknown device type %d\n", arizona->type); return -EINVAL; } /* Mark DCVDD as external, LDO1 driver will clear if internal */ arizona->external_dcvdd = true; ret = mfd_add_devices(arizona->dev, -1, early_devs, ARRAY_SIZE(early_devs), NULL, 0, NULL); if (ret != 0) { dev_err(dev, "Failed to add early children: %d\n", ret); return ret; } ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to request core supplies: %d\n", ret); goto err_early; } /** * Don't use devres here because the only device we have to get * against is the MFD device and DCVDD will likely be supplied by * one of its children. Meaning that the regulator will be * destroyed by the time devres calls regulator put. */ arizona->dcvdd = regulator_get(arizona->dev, "DCVDD"); if (IS_ERR(arizona->dcvdd)) { ret = PTR_ERR(arizona->dcvdd); dev_err(dev, "Failed to request DCVDD: %d\n", ret); goto err_early; } if (arizona->pdata.reset) { /* Start out with /RESET low to put the chip into reset */ ret = gpio_request_one(arizona->pdata.reset, GPIOF_DIR_OUT | GPIOF_INIT_LOW, "arizona /RESET"); if (ret != 0) { dev_err(dev, "Failed to request /RESET: %d\n", ret); goto err_dcvdd; } } ret = regulator_bulk_enable(arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to enable core supplies: %d\n", ret); goto err_dcvdd; } ret = regulator_enable(arizona->dcvdd); if (ret != 0) { dev_err(dev, "Failed to enable DCVDD: %d\n", ret); goto err_enable; } if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 1); msleep(1); } regcache_cache_only(arizona->regmap, false); /* Verify that this is a chip we know about */ ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(dev, "Failed to read ID register: %d\n", ret); goto err_reset; } switch (reg) { case 0x5102: case 0x5110: case 0x8997: break; default: dev_err(arizona->dev, "Unknown device ID: %x\n", reg); goto err_reset; } /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { regcache_mark_dirty(arizona->regmap); ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_reset; } msleep(1); ret = regcache_sync(arizona->regmap); if (ret != 0) { dev_err(dev, "Failed to sync device: %d\n", ret); goto err_reset; } } /* Ensure device startup is complete */ switch (arizona->type) { case WM5102: ret = regmap_read(arizona->regmap, 0x19, &val); if (ret != 0) dev_err(dev, "Failed to check write sequencer state: %d\n", ret); else if (val & 0x01) break; /* Fall through */ default: ret = arizona_wait_for_boot(arizona); if (ret != 0) { dev_err(arizona->dev, "Device failed initial boot: %d\n", ret); goto err_reset; } break; } /* Read the device ID information & do device specific stuff */ ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(dev, "Failed to read ID register: %d\n", ret); goto err_reset; } ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION, &arizona->rev); if (ret != 0) { dev_err(dev, "Failed to read revision register: %d\n", ret); goto err_reset; } arizona->rev &= ARIZONA_DEVICE_REVISION_MASK; switch (reg) { #ifdef CONFIG_MFD_WM5102 case 0x5102: type_name = "WM5102"; if (arizona->type != WM5102) { dev_err(arizona->dev, "WM5102 registered as %d\n", arizona->type); arizona->type = WM5102; } apply_patch = wm5102_patch; arizona->rev &= 0x7; break; #endif #ifdef CONFIG_MFD_WM5110 case 0x5110: type_name = "WM5110"; if (arizona->type != WM5110) { dev_err(arizona->dev, "WM5110 registered as %d\n", arizona->type); arizona->type = WM5110; } apply_patch = wm5110_patch; break; #endif #ifdef CONFIG_MFD_WM8997 case 0x8997: type_name = "WM8997"; if (arizona->type != WM8997) { dev_err(arizona->dev, "WM8997 registered as %d\n", arizona->type); arizona->type = WM8997; } apply_patch = wm8997_patch; break; #endif default: dev_err(arizona->dev, "Unknown device ID %x\n", reg); goto err_reset; } dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A'); if (apply_patch) { ret = apply_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err_reset; } switch (arizona->type) { case WM5102: ret = arizona_apply_hardware_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply hardware patch: %d\n", ret); goto err_reset; } break; default: break; } } for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { if (!arizona->pdata.gpio_defaults[i]) continue; regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i, arizona->pdata.gpio_defaults[i]); } pm_runtime_set_autosuspend_delay(arizona->dev, 100); pm_runtime_use_autosuspend(arizona->dev); pm_runtime_enable(arizona->dev); /* Chip default */ if (!arizona->pdata.clk32k_src) arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2; switch (arizona->pdata.clk32k_src) { case ARIZONA_32KZ_MCLK1: case ARIZONA_32KZ_MCLK2: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, arizona->pdata.clk32k_src - 1); arizona_clk32k_enable(arizona); break; case ARIZONA_32KZ_NONE: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, 2); break; default: dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n", arizona->pdata.clk32k_src); ret = -EINVAL; goto err_reset; } for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) { if (!arizona->pdata.micbias[i].mV && !arizona->pdata.micbias[i].bypass) continue; /* Apply default for bypass mode */ if (!arizona->pdata.micbias[i].mV) arizona->pdata.micbias[i].mV = 2800; val = (arizona->pdata.micbias[i].mV - 1500) / 100; val <<= ARIZONA_MICB1_LVL_SHIFT; if (arizona->pdata.micbias[i].ext_cap) val |= ARIZONA_MICB1_EXT_CAP; if (arizona->pdata.micbias[i].discharge) val |= ARIZONA_MICB1_DISCH; if (arizona->pdata.micbias[i].soft_start) val |= ARIZONA_MICB1_RATE; if (arizona->pdata.micbias[i].bypass) val |= ARIZONA_MICB1_BYPASS; regmap_update_bits(arizona->regmap, ARIZONA_MIC_BIAS_CTRL_1 + i, ARIZONA_MICB1_LVL_MASK | ARIZONA_MICB1_DISCH | ARIZONA_MICB1_BYPASS | ARIZONA_MICB1_RATE, val); } for (i = 0; i < ARIZONA_MAX_INPUT; i++) { /* Default for both is 0 so noop with defaults */ val = arizona->pdata.dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT; val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT; regmap_update_bits(arizona->regmap, ARIZONA_IN1L_CONTROL + (i * 8), ARIZONA_IN1_DMIC_SUP_MASK | ARIZONA_IN1_MODE_MASK, val); } for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) { /* Default is 0 so noop with defaults */ if (arizona->pdata.out_mono[i]) val = ARIZONA_OUT1_MONO; else val = 0; regmap_update_bits(arizona->regmap, ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8), ARIZONA_OUT1_MONO, val); } for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) { if (arizona->pdata.spk_mute[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_1 + (i * 2), ARIZONA_SPK1_MUTE_ENDIAN_MASK | ARIZONA_SPK1_MUTE_SEQ1_MASK, arizona->pdata.spk_mute[i]); if (arizona->pdata.spk_fmt[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_2 + (i * 2), ARIZONA_SPK1_FMT_MASK, arizona->pdata.spk_fmt[i]); } /* Set up for interrupts */ ret = arizona_irq_init(arizona); if (ret != 0) goto err_reset; arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error", arizona_clkgen_err, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked", arizona_overclocked, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked", arizona_underclocked, arizona); switch (arizona->type) { case WM5102: ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, ARRAY_SIZE(wm5110_devs), NULL, 0, NULL); break; case WM8997: ret = mfd_add_devices(arizona->dev, -1, wm8997_devs, ARRAY_SIZE(wm8997_devs), NULL, 0, NULL); break; } if (ret != 0) { dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret); goto err_irq; } #ifdef CONFIG_PM_RUNTIME regulator_disable(arizona->dcvdd); #endif return 0; err_irq: arizona_irq_exit(arizona); err_reset: if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 0); gpio_free(arizona->pdata.reset); } regulator_disable(arizona->dcvdd); err_enable: regulator_bulk_disable(arizona->num_core_supplies, arizona->core_supplies); err_dcvdd: regulator_put(arizona->dcvdd); err_early: mfd_remove_devices(dev); return ret; }
static int wm9081_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_SEL_MASK, 0x2); snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_STBY_BIAS_ENA, 0); break; case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { regcache_cache_only(wm9081->regmap, false); regcache_sync(wm9081->regmap); snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, WM9081_LINEOUT_DISCH, 0); snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_BIAS_SRC | WM9081_BIAS_ENA, WM9081_BIAS_SRC | WM9081_BIAS_ENA); snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK, WM9081_VMID_RAMP | 0x6); mdelay(100); snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_RAMP, 0); snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_BIAS_SRC, 0); } snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_SEL_MASK, 0x04); snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_STBY_BIAS_ENA, WM9081_STBY_BIAS_ENA); break; case SND_SOC_BIAS_OFF: snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_BIAS_SRC | WM9081_BIAS_ENA, WM9081_BIAS_SRC); snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK, WM9081_VMID_RAMP); snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, WM9081_LINEOUT_DISCH, WM9081_LINEOUT_DISCH); regcache_cache_only(wm9081->regmap, true); break; } codec->dapm.bias_level = level; return 0; }
static int tegra30_ahub_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct tegra30_ahub_soc_data *soc_data; struct reset_control *rst; int i; struct resource *res0, *res1; void __iomem *regs_apbif, *regs_ahub; int ret = 0; if (ahub) return -ENODEV; match = of_match_device(tegra30_ahub_of_match, &pdev->dev); if (!match) return -EINVAL; soc_data = match->data; /* * The AHUB hosts a register bus: the "configlink". For this to * operate correctly, all devices on this bus must be out of reset. * Ensure that here. */ for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) { if (!(configlink_mods[i].mod_list_mask & soc_data->mod_list_mask)) continue; rst = reset_control_get_exclusive(&pdev->dev, configlink_mods[i].rst_name); if (IS_ERR(rst)) { dev_err(&pdev->dev, "Can't get reset %s\n", configlink_mods[i].rst_name); ret = PTR_ERR(rst); return ret; } ret = reset_control_deassert(rst); reset_control_put(rst); if (ret) return ret; } ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), GFP_KERNEL); if (!ahub) return -ENOMEM; dev_set_drvdata(&pdev->dev, ahub); ahub->soc_data = soc_data; ahub->dev = &pdev->dev; ahub->clk_d_audio = devm_clk_get(&pdev->dev, "d_audio"); if (IS_ERR(ahub->clk_d_audio)) { dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n"); ret = PTR_ERR(ahub->clk_d_audio); return ret; } ahub->clk_apbif = devm_clk_get(&pdev->dev, "apbif"); if (IS_ERR(ahub->clk_apbif)) { dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n"); ret = PTR_ERR(ahub->clk_apbif); return ret; } res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs_apbif = devm_ioremap_resource(&pdev->dev, res0); if (IS_ERR(regs_apbif)) return PTR_ERR(regs_apbif); ahub->apbif_addr = res0->start; ahub->regmap_apbif = devm_regmap_init_mmio(&pdev->dev, regs_apbif, &tegra30_ahub_apbif_regmap_config); if (IS_ERR(ahub->regmap_apbif)) { dev_err(&pdev->dev, "apbif regmap init failed\n"); ret = PTR_ERR(ahub->regmap_apbif); return ret; } regcache_cache_only(ahub->regmap_apbif, true); res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); regs_ahub = devm_ioremap_resource(&pdev->dev, res1); if (IS_ERR(regs_ahub)) return PTR_ERR(regs_ahub); ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub, &tegra30_ahub_ahub_regmap_config); if (IS_ERR(ahub->regmap_ahub)) { dev_err(&pdev->dev, "ahub regmap init failed\n"); ret = PTR_ERR(ahub->regmap_ahub); return ret; } regcache_cache_only(ahub->regmap_ahub, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra30_ahub_runtime_resume(&pdev->dev); if (ret) goto err_pm_disable; } of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); return ret; }
static int wm8993_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); int ret; wm_hubs_set_bias_level(codec, level); switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: /* VMID=2*40k */ snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, WM8993_VMID_SEL_MASK, 0x2); snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2, WM8993_TSHUT_ENA, WM8993_TSHUT_ENA); break; case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) return ret; regcache_cache_only(wm8993->regmap, false); regcache_sync(wm8993->regmap); wm_hubs_vmid_ena(codec); /* Bring up VMID with fast soft start */ snd_soc_update_bits(codec, WM8993_ANTIPOP2, WM8993_STARTUP_BIAS_ENA | WM8993_VMID_BUF_ENA | WM8993_VMID_RAMP_MASK | WM8993_BIAS_SRC, WM8993_STARTUP_BIAS_ENA | WM8993_VMID_BUF_ENA | WM8993_VMID_RAMP_MASK | WM8993_BIAS_SRC); /* If either line output is single ended we * need the VMID buffer */ if (!wm8993->pdata.lineout1_diff || !wm8993->pdata.lineout2_diff) snd_soc_update_bits(codec, WM8993_ANTIPOP1, WM8993_LINEOUT_VMID_BUF_ENA, WM8993_LINEOUT_VMID_BUF_ENA); /* VMID=2*40k */ snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, WM8993_BIAS_ENA | 0x2); msleep(32); /* Switch to normal bias */ snd_soc_update_bits(codec, WM8993_ANTIPOP2, WM8993_BIAS_SRC | WM8993_STARTUP_BIAS_ENA, 0); } /* VMID=2*240k */ snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, WM8993_VMID_SEL_MASK, 0x4); snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2, WM8993_TSHUT_ENA, 0); break; case SND_SOC_BIAS_OFF: snd_soc_update_bits(codec, WM8993_ANTIPOP1, WM8993_LINEOUT_VMID_BUF_ENA, 0); snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 0); snd_soc_update_bits(codec, WM8993_ANTIPOP2, WM8993_STARTUP_BIAS_ENA | WM8993_VMID_BUF_ENA | WM8993_VMID_RAMP_MASK | WM8993_BIAS_SRC, 0); regcache_cache_only(wm8993->regmap, true); regcache_mark_dirty(wm8993->regmap); regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); break; } codec->dapm.bias_level = level; return 0; }
static int tegra30_i2s_platform_probe(struct platform_device *pdev) { struct tegra30_i2s *i2s; const struct of_device_id *match; u32 cif_ids[2]; struct resource *mem, *memregion; void __iomem *regs; int ret; i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL); if (!i2s) { dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n"); ret = -ENOMEM; goto err; } dev_set_drvdata(&pdev->dev, i2s); match = of_match_device(tegra30_i2s_of_match, &pdev->dev); if (!match) { dev_err(&pdev->dev, "Error: No device match found\n"); ret = -ENODEV; goto err; } i2s->soc_data = (struct tegra30_i2s_soc_data *)match->data; i2s->dai = tegra30_i2s_dai_template; i2s->dai.name = dev_name(&pdev->dev); ret = of_property_read_u32_array(pdev->dev.of_node, "nvidia,ahub-cif-ids", cif_ids, ARRAY_SIZE(cif_ids)); if (ret < 0) goto err; i2s->playback_i2s_cif = cif_ids[0]; i2s->capture_i2s_cif = cif_ids[1]; i2s->clk_i2s = clk_get(&pdev->dev, NULL); if (IS_ERR(i2s->clk_i2s)) { dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); ret = PTR_ERR(i2s->clk_i2s); goto err; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "No memory resource\n"); ret = -ENODEV; goto err_clk_put; } memregion = devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), DRV_NAME); if (!memregion) { dev_err(&pdev->dev, "Memory region already claimed\n"); ret = -EBUSY; goto err_clk_put; } regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto err_clk_put; } i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &tegra30_i2s_regmap_config); if (IS_ERR(i2s->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); ret = PTR_ERR(i2s->regmap); goto err_clk_put; } regcache_cache_only(i2s->regmap, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra30_i2s_runtime_resume(&pdev->dev); if (ret) goto err_pm_disable; } i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->playback_dma_data.maxburst = 4; ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, i2s->playback_dma_chan, sizeof(i2s->playback_dma_chan), &i2s->playback_dma_data.addr); if (ret) { dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret); goto err_suspend; } ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, i2s->playback_fifo_cif); if (ret) { dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); goto err_free_tx_fifo; } i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->capture_dma_data.maxburst = 4; ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, i2s->capture_dma_chan, sizeof(i2s->capture_dma_chan), &i2s->capture_dma_data.addr); if (ret) { dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret); goto err_unroute_tx_fifo; } ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, i2s->capture_i2s_cif); if (ret) { dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); goto err_free_rx_fifo; } ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, &i2s->dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; goto err_unroute_rx_fifo; } ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev, &i2s->dma_config, i2s->playback_dma_chan, i2s->capture_dma_chan); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); goto err_unregister_component; } return 0; err_unregister_component: snd_soc_unregister_component(&pdev->dev); err_unroute_rx_fifo: tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); err_free_rx_fifo: tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); err_unroute_tx_fifo: tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); err_free_tx_fifo: tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) tegra30_i2s_runtime_suspend(&pdev->dev); err_pm_disable: pm_runtime_disable(&pdev->dev); err_clk_put: clk_put(i2s->clk_i2s); err: return ret; }
static int wm8994_suspend(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; /* Don't actually go through with the suspend if the CODEC is * still active (eg, for audio passthrough from CP. */ ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & WM8994_VMID_SEL_MASK) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA | WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA | WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA | WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA | WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } switch (wm8994->type) { case WM8958: case WM1811: ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & WM8958_MICD_ENA) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } break; default: break; } switch (wm8994->type) { case WM1811: ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2); if (ret < 0) { dev_err(dev, "Failed to read jackdet: %d\n", ret); } else if (ret & WM1811_JACKDET_MODE_MASK) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } break; default: break; } switch (wm8994->type) { case WM1811: ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2); if (ret < 0) { dev_err(dev, "Failed to read jackdet: %d\n", ret); } else if (ret & WM1811_JACKDET_MODE_MASK) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } break; default: break; } /* Disable LDO pulldowns while the device is suspended if we * don't know that something will be driving them. */ if (!wm8994->ldo_ena_always_driven) wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD); /* Explicitly put the device into reset in case regulators * don't get disabled in order to ensure consistent restart. */ wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET)); regcache_cache_only(wm8994->regmap, true); regcache_mark_dirty(wm8994->regmap); wm8994->suspended = true; ret = regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to disable supplies: %d\n", ret); return ret; } return 0; }
static int wm9081_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: /* VMID=2*40k */ snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_SEL_MASK, 0x2); /* Normal bias current */ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_STBY_BIAS_ENA, 0); break; case SND_SOC_BIAS_STANDBY: /* Initial cold start */ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { regcache_cache_only(wm9081->regmap, false); regcache_sync(wm9081->regmap); /* Disable LINEOUT discharge */ snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, WM9081_LINEOUT_DISCH, 0); /* Select startup bias source */ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_BIAS_SRC | WM9081_BIAS_ENA, WM9081_BIAS_SRC | WM9081_BIAS_ENA); /* VMID 2*4k; Soft VMID ramp enable */ snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK, WM9081_VMID_RAMP | 0x6); mdelay(100); /* Normal bias enable & soft start off */ snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_RAMP, 0); /* Standard bias source */ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_BIAS_SRC, 0); } /* VMID 2*240k */ snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_SEL_MASK, 0x04); /* Standby bias current on */ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_STBY_BIAS_ENA, WM9081_STBY_BIAS_ENA); break; case SND_SOC_BIAS_OFF: /* Startup bias source and disable bias */ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, WM9081_BIAS_SRC | WM9081_BIAS_ENA, WM9081_BIAS_SRC); /* Disable VMID with soft ramping */ snd_soc_update_bits(codec, WM9081_VMID_CONTROL, WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK, WM9081_VMID_RAMP); /* Actively discharge LINEOUT */ snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, WM9081_LINEOUT_DISCH, WM9081_LINEOUT_DISCH); regcache_cache_only(wm9081->regmap, true); break; } return 0; }
int twl6040_power(struct twl6040 *twl6040, int on) { int ret = 0; mutex_lock(&twl6040->mutex); if (on) { /* already powered-up */ if (twl6040->power_count++) goto out; clk_prepare_enable(twl6040->clk32k); /* Allow writes to the chip */ regcache_cache_only(twl6040->regmap, false); if (gpio_is_valid(twl6040->audpwron)) { /* use automatic power-up sequence */ ret = twl6040_power_up_automatic(twl6040); if (ret) { twl6040->power_count = 0; goto out; } } else { /* use manual power-up sequence */ ret = twl6040_power_up_manual(twl6040); if (ret) { twl6040->power_count = 0; goto out; } } /* Sync with the HW */ regcache_sync(twl6040->regmap); /* Default PLL configuration after power up */ twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; twl6040->sysclk = 19200000; twl6040->mclk = 32768; } else { /* already powered-down */ if (!twl6040->power_count) { dev_err(twl6040->dev, "device is already powered-off\n"); ret = -EPERM; goto out; } if (--twl6040->power_count) goto out; if (gpio_is_valid(twl6040->audpwron)) { /* use AUDPWRON line */ gpio_set_value(twl6040->audpwron, 0); /* power-down sequence latency */ usleep_range(500, 700); } else { /* use manual power-down sequence */ twl6040_power_down_manual(twl6040); } /* Set regmap to cache only and mark it as dirty */ regcache_cache_only(twl6040->regmap, true); regcache_mark_dirty(twl6040->regmap); twl6040->sysclk = 0; twl6040->mclk = 0; clk_disable_unprepare(twl6040->clk32k); } out: mutex_unlock(&twl6040->mutex); return ret; }
static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { struct cs42l73_private *cs42l73; int ret; unsigned int devid = 0; unsigned int reg; cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private), GFP_KERNEL); if (!cs42l73) { dev_err(&i2c_client->dev, "could not allocate codec\n"); return -ENOMEM; } i2c_set_clientdata(i2c_client, cs42l73); cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap); if (IS_ERR(cs42l73->regmap)) { ret = PTR_ERR(cs42l73->regmap); dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); goto err; } /* initialize codec */ ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); devid = (reg & 0xFF) << 12; ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, ®); devid |= (reg & 0xFF) << 4; ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®); devid |= (reg & 0xF0) >> 4; if (devid != CS42L73_DEVID) { ret = -ENODEV; dev_err(&i2c_client->dev, "CS42L73 Device ID (%X). Expected %X\n", devid, CS42L73_DEVID); goto err_regmap; } ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); if (ret < 0) { dev_err(&i2c_client->dev, "Get Revision ID failed\n"); goto err_regmap; } dev_info(&i2c_client->dev, "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF); regcache_cache_only(cs42l73->regmap, true); ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_cs42l73, cs42l73_dai, ARRAY_SIZE(cs42l73_dai)); if (ret < 0) goto err_regmap; return 0; err_regmap: regmap_exit(cs42l73->regmap); err: return ret; }
static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev) { struct mtk_base_afe *afe; struct mt8183_afe_private *afe_priv; struct device *dev; int i, irq_id, ret; afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); if (!afe) return -ENOMEM; platform_set_drvdata(pdev, afe); afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), GFP_KERNEL); if (!afe->platform_priv) return -ENOMEM; afe_priv = afe->platform_priv; afe->dev = &pdev->dev; dev = afe->dev; /* initial audio related clock */ ret = mt8183_init_clock(afe); if (ret) { dev_err(dev, "init clock error\n"); return ret; } pm_runtime_enable(dev); /* regmap init */ afe->regmap = syscon_node_to_regmap(dev->parent->of_node); if (IS_ERR(afe->regmap)) { dev_err(dev, "could not get regmap from parent\n"); return PTR_ERR(afe->regmap); } ret = regmap_attach_dev(dev, afe->regmap, &mt8183_afe_regmap_config); if (ret) { dev_warn(dev, "regmap_attach_dev fail, ret %d\n", ret); return ret; } /* enable clock for regcache get default value from hw */ afe_priv->pm_runtime_bypass_reg_ctl = true; pm_runtime_get_sync(&pdev->dev); ret = regmap_reinit_cache(afe->regmap, &mt8183_afe_regmap_config); if (ret) { dev_err(dev, "regmap_reinit_cache fail, ret %d\n", ret); return ret; } pm_runtime_put_sync(&pdev->dev); afe_priv->pm_runtime_bypass_reg_ctl = false; regcache_cache_only(afe->regmap, true); regcache_mark_dirty(afe->regmap); pm_runtime_get_sync(&pdev->dev); /* init memif */ afe->memif_size = MT8183_MEMIF_NUM; afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), GFP_KERNEL); if (!afe->memif) return -ENOMEM; for (i = 0; i < afe->memif_size; i++) { afe->memif[i].data = &memif_data[i]; afe->memif[i].irq_usage = -1; } afe->memif[MT8183_MEMIF_HDMI].irq_usage = MT8183_IRQ_8; afe->memif[MT8183_MEMIF_HDMI].const_irq = 1; mutex_init(&afe->irq_alloc_lock); /* init memif */ /* irq initialize */ afe->irqs_size = MT8183_IRQ_NUM; afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), GFP_KERNEL); if (!afe->irqs) return -ENOMEM; for (i = 0; i < afe->irqs_size; i++) afe->irqs[i].irq_data = &irq_data[i]; /* request irq */ irq_id = platform_get_irq(pdev, 0); if (!irq_id) { dev_err(dev, "%pOFn no irq found\n", dev->of_node); return -ENXIO; } ret = devm_request_irq(dev, irq_id, mt8183_afe_irq_handler, IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); if (ret) { dev_err(dev, "could not request_irq for asys-isr\n"); return ret; } /* init sub_dais */ INIT_LIST_HEAD(&afe->sub_dais); for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) { ret = dai_register_cbs[i](afe); if (ret) { dev_warn(afe->dev, "dai register i %d fail, ret %d\n", i, ret); return ret; } } /* init dai_driver and component_driver */ ret = mtk_afe_combine_sub_dai(afe); if (ret) { dev_warn(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n", ret); return ret; } afe->mtk_afe_hardware = &mt8183_afe_hardware; afe->memif_fs = mt8183_memif_fs; afe->irq_fs = mt8183_irq_fs; afe->runtime_resume = mt8183_afe_runtime_resume; afe->runtime_suspend = mt8183_afe_runtime_suspend; /* register component */ ret = devm_snd_soc_register_component(&pdev->dev, &mt8183_afe_component, NULL, 0); if (ret) { dev_warn(dev, "err_platform\n"); return ret; } ret = devm_snd_soc_register_component(afe->dev, &mt8183_afe_pcm_dai_component, afe->dai_drivers, afe->num_dai_drivers); if (ret) { dev_warn(dev, "err_dai_component\n"); return ret; } return ret; }
int __devinit arizona_dev_init(struct arizona *arizona) { struct device *dev = arizona->dev; const char *type_name; unsigned int reg, val; int (*apply_patch)(struct arizona *) = NULL; int ret, i; dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock); if (dev_get_platdata(arizona->dev)) memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), sizeof(arizona->pdata)); regcache_cache_only(arizona->regmap, true); switch (arizona->type) { case WM5102: case WM5110: for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) arizona->core_supplies[i].supply = wm5102_core_supplies[i]; arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies); break; default: dev_err(arizona->dev, "Unknown device type %d\n", arizona->type); return -EINVAL; } ret = mfd_add_devices(arizona->dev, -1, early_devs, ARRAY_SIZE(early_devs), NULL, 0); if (ret != 0) { dev_err(dev, "Failed to add early children: %d\n", ret); return ret; } ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to request core supplies: %d\n", ret); goto err_early; } arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD"); if (IS_ERR(arizona->dcvdd)) { ret = PTR_ERR(arizona->dcvdd); dev_err(dev, "Failed to request DCVDD: %d\n", ret); goto err_early; } ret = regulator_bulk_enable(arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to enable core supplies: %d\n", ret); goto err_early; } ret = regulator_enable(arizona->dcvdd); if (ret != 0) { dev_err(dev, "Failed to enable DCVDD: %d\n", ret); goto err_enable; } if (arizona->pdata.control_init_time) msleep(arizona->pdata.control_init_time); if (arizona->pdata.reset) { /* Start out with /RESET low to put the chip into reset */ ret = gpio_request_one(arizona->pdata.reset, GPIOF_DIR_OUT | GPIOF_INIT_LOW, "arizona /RESET"); if (ret != 0) { dev_err(dev, "Failed to request /RESET: %d\n", ret); goto err_dcvdd; } gpio_set_value_cansleep(arizona->pdata.reset, 1); } regcache_cache_only(arizona->regmap, false); ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(dev, "Failed to read ID register: %d\n", ret); goto err_reset; } ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION, &arizona->rev); if (ret != 0) { dev_err(dev, "Failed to read revision register: %d\n", ret); goto err_reset; } arizona->rev &= ARIZONA_DEVICE_REVISION_MASK; switch (reg) { #ifdef CONFIG_MFD_WM5102 case 0x5102: type_name = "WM5102"; if (arizona->type != WM5102) { dev_err(arizona->dev, "WM5102 registered as %d\n", arizona->type); arizona->type = WM5102; } apply_patch = wm5102_patch; break; #endif #ifdef CONFIG_MFD_WM5110 case 0x5110: type_name = "WM5110"; if (arizona->type != WM5110) { dev_err(arizona->dev, "WM5110 registered as %d\n", arizona->type); arizona->type = WM5110; } apply_patch = wm5110_patch; break; #endif default: dev_err(arizona->dev, "Unknown device ID %x\n", reg); goto err_reset; } dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A'); /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_reset; } } ret = arizona_wait_for_boot(arizona); if (ret != 0) { dev_err(arizona->dev, "Device failed initial boot: %d\n", ret); goto err_reset; } if (apply_patch) { ret = apply_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err_reset; } } for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { if (!arizona->pdata.gpio_defaults[i]) continue; regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i, arizona->pdata.gpio_defaults[i]); } pm_runtime_enable(arizona->dev); /* Chip default */ if (!arizona->pdata.clk32k_src) arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2; switch (arizona->pdata.clk32k_src) { case ARIZONA_32KZ_MCLK1: case ARIZONA_32KZ_MCLK2: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, arizona->pdata.clk32k_src - 1); break; case ARIZONA_32KZ_NONE: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, 2); break; default: dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n", arizona->pdata.clk32k_src); ret = -EINVAL; goto err_reset; } for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) { if (!arizona->pdata.micbias[i].mV && !arizona->pdata.micbias[i].bypass) continue; /* Apply default for bypass mode */ if (!arizona->pdata.micbias[i].mV) arizona->pdata.micbias[i].mV = 2800; val = (arizona->pdata.micbias[i].mV - 1500) / 100; val <<= ARIZONA_MICB1_LVL_SHIFT; if (arizona->pdata.micbias[i].ext_cap) val |= ARIZONA_MICB1_EXT_CAP; if (arizona->pdata.micbias[i].discharge) val |= ARIZONA_MICB1_DISCH; if (arizona->pdata.micbias[i].fast_start) val |= ARIZONA_MICB1_RATE; if (arizona->pdata.micbias[i].bypass) val |= ARIZONA_MICB1_BYPASS; regmap_update_bits(arizona->regmap, ARIZONA_MIC_BIAS_CTRL_1 + i, ARIZONA_MICB1_LVL_MASK | ARIZONA_MICB1_DISCH | ARIZONA_MICB1_BYPASS | ARIZONA_MICB1_RATE, val); } for (i = 0; i < ARIZONA_MAX_INPUT; i++) { /* Default for both is 0 so noop with defaults */ val = arizona->pdata.dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT; val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT; regmap_update_bits(arizona->regmap, ARIZONA_IN1L_CONTROL + (i * 8), ARIZONA_IN1_DMIC_SUP_MASK | ARIZONA_IN1_MODE_MASK, val); } for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) { /* Default is 0 so noop with defaults */ if (arizona->pdata.out_mono[i]) val = ARIZONA_OUT1_MONO; else val = 0; regmap_update_bits(arizona->regmap, ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8), ARIZONA_OUT1_MONO, val); } for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) { if (arizona->pdata.spk_mute[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_1 + (i * 2), ARIZONA_SPK1_MUTE_ENDIAN_MASK | ARIZONA_SPK1_MUTE_SEQ1_MASK, arizona->pdata.spk_mute[i]); if (arizona->pdata.spk_fmt[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_2 + (i * 2), ARIZONA_SPK1_FMT_MASK, arizona->pdata.spk_fmt[i]); } /* set virtual IRQs */ arizona->virq[0] = arizona->pdata.irq_base; arizona->virq[1] = arizona->pdata.irq_base + ARIZONA_NUM_IRQ; switch (arizona->pdata.mic_spk_clamp) { case ARIZONA_MIC_CLAMP_SPKLN: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2, 0x3c, 0xc); break; case ARIZONA_MIC_CLAMP_SPKLP: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2, 0x3c, 0x1c); break; case ARIZONA_MIC_CLAMP_SPKRN: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3, 0x3c, 0xc); break; case ARIZONA_MIC_CLAMP_SPKRP: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3, 0x3c, 0x1c); break; default: break; } /* Set up for interrupts */ ret = arizona_irq_init(arizona); if (ret != 0) goto err_reset; arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error", arizona_clkgen_err, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked", arizona_overclocked, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked", arizona_underclocked, arizona); switch (arizona->type) { case WM5102: ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, ARRAY_SIZE(wm5102_devs), NULL, 0); break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, ARRAY_SIZE(wm5110_devs), NULL, 0); break; } if (ret != 0) { dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret); goto err_irq; } if (arizona->pdata.init_done) arizona->pdata.init_done(); #ifdef CONFIG_PM_RUNTIME regulator_disable(arizona->dcvdd); #endif return 0; err_irq: arizona_irq_exit(arizona); err_reset: if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 1); gpio_free(arizona->pdata.reset); } err_dcvdd: regulator_disable(arizona->dcvdd); err_enable: regulator_bulk_disable(arizona->num_core_supplies, arizona->core_supplies); err_early: mfd_remove_devices(dev); return ret; }
static int arizona_runtime_resume(struct device *dev) { struct arizona *arizona = dev_get_drvdata(dev); int ret; dev_dbg(arizona->dev, "Leaving AoD mode\n"); ret = regulator_enable(arizona->dcvdd); if (ret != 0) { dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret); return ret; } regcache_cache_only(arizona->regmap, false); switch (arizona->type) { case WM5102: if (arizona->external_dcvdd) { ret = regmap_update_bits(arizona->regmap, ARIZONA_ISOLATION_CONTROL, ARIZONA_ISOLATE_DCVDD1, 0); if (ret != 0) { dev_err(arizona->dev, "Failed to connect DCVDD: %d\n", ret); goto err; } } ret = wm5102_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err; } ret = arizona_apply_hardware_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply hardware patch: %d\n", ret); goto err; } break; default: ret = arizona_wait_for_boot(arizona); if (ret != 0) { goto err; } if (arizona->external_dcvdd) { ret = regmap_update_bits(arizona->regmap, ARIZONA_ISOLATION_CONTROL, ARIZONA_ISOLATE_DCVDD1, 0); if (ret != 0) { dev_err(arizona->dev, "Failed to connect DCVDD: %d\n", ret); goto err; } } break; } switch (arizona->type) { case WM5102: ret = wm5102_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err; } default: break; } ret = regcache_sync(arizona->regmap); if (ret != 0) { dev_err(arizona->dev, "Failed to restore register cache\n"); goto err; } return 0; err: regcache_cache_only(arizona->regmap, true); regulator_disable(arizona->dcvdd); return ret; }
static int adau1977_power_enable(struct adau1977 *adau1977) { unsigned int val; int ret = 0; if (adau1977->enabled) return 0; ret = regulator_enable(adau1977->avdd_reg); if (ret) return ret; if (adau1977->dvdd_reg) { ret = regulator_enable(adau1977->dvdd_reg); if (ret) goto err_disable_avdd; } if (adau1977->reset_gpio) gpiod_set_value_cansleep(adau1977->reset_gpio, 1); regcache_cache_only(adau1977->regmap, false); if (adau1977->switch_mode) adau1977->switch_mode(adau1977->dev); ret = adau1977_reset(adau1977); if (ret) goto err_disable_dvdd; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER, ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP); if (ret) goto err_disable_dvdd; ret = regcache_sync(adau1977->regmap); if (ret) goto err_disable_dvdd; /* * The PLL register is not affected by the software reset. It is * possible that the value of the register was changed to the * default value while we were in cache only mode. In this case * regcache_sync will skip over it and we have to manually sync * it. */ ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val); if (ret) goto err_disable_dvdd; if (val == 0x41) { regcache_cache_bypass(adau1977->regmap, true); ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL, 0x41); if (ret) goto err_disable_dvdd; regcache_cache_bypass(adau1977->regmap, false); } adau1977->enabled = true; return ret; err_disable_dvdd: if (adau1977->dvdd_reg) regulator_disable(adau1977->dvdd_reg); err_disable_avdd: regulator_disable(adau1977->avdd_reg); return ret; }
static int wm8993_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8993_priv *wm8993; unsigned int reg; int ret, i; wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), GFP_KERNEL); if (wm8993 == NULL) return -ENOMEM; wm8993->dev = &i2c->dev; init_completion(&wm8993->fll_lock); wm8993->regmap = devm_regmap_init_i2c(i2c, &wm8993_regmap); if (IS_ERR(wm8993->regmap)) { ret = PTR_ERR(wm8993->regmap); dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); return ret; } i2c_set_clientdata(i2c, wm8993); for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) wm8993->supplies[i].supply = wm8993_supply_names[i]; ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); return ret; } ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); return ret; } ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); goto err_enable; } if (reg != 0x8993) { dev_err(&i2c->dev, "Invalid ID register value %x\n", reg); ret = -EINVAL; goto err_enable; } ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff); if (ret != 0) goto err_enable; ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch, ARRAY_SIZE(wm8993_regmap_patch)); if (ret != 0) dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n", ret); if (i2c->irq) { /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */ ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1, WM8993_GPIO1_PD | WM8993_GPIO1_SEL_MASK, 7); if (ret != 0) goto err_enable; ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "wm8993", wm8993); if (ret != 0) goto err_enable; } regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); regcache_cache_only(wm8993->regmap, true); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8993, &wm8993_dai, 1); if (ret != 0) { dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); goto err_irq; } return 0; err_irq: if (i2c->irq) free_irq(i2c->irq, wm8993); err_enable: regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); return ret; }
static int wm8994_suspend(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & WM8994_VMID_SEL_MASK) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA | WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA | WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA | WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA | WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } switch (wm8994->type) { case WM8958: case WM1811: ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); } else if (ret & WM8958_MICD_ENA) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } break; default: break; } switch (wm8994->type) { case WM1811: ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2); if (ret < 0) { dev_err(dev, "Failed to read jackdet: %d\n", ret); } else if (ret & WM1811_JACKDET_MODE_MASK) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } break; default: break; } switch (wm8994->type) { case WM1811: ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2); if (ret < 0) { dev_err(dev, "Failed to read jackdet: %d\n", ret); } else if (ret & WM1811_JACKDET_MODE_MASK) { dev_dbg(dev, "CODEC still active, ignoring suspend\n"); return 0; } break; default: break; } if (!wm8994->ldo_ena_always_driven) wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD); wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET)); regcache_cache_only(wm8994->regmap, true); regcache_mark_dirty(wm8994->regmap); wm8994->suspended = true; ret = regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to disable supplies: %d\n", ret); return ret; } return 0; }
static int tegra30_ahub_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct tegra30_ahub_soc_data *soc_data; struct clk *clk; int i; struct resource *res0, *res1, *region; u32 of_dma[2]; void __iomem *regs_apbif, *regs_ahub; int ret = 0; if (ahub) return -ENODEV; match = of_match_device(tegra30_ahub_of_match, &pdev->dev); if (!match) return -EINVAL; soc_data = match->data; /* * The AHUB hosts a register bus: the "configlink". For this to * operate correctly, all devices on this bus must be out of reset. * Ensure that here. */ for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { if (!(configlink_clocks[i].clk_list_mask & soc_data->clk_list_mask)) continue; clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name); if (IS_ERR(clk)) { dev_err(&pdev->dev, "Can't get clock %s\n", configlink_clocks[i].clk_name); ret = PTR_ERR(clk); goto err; } tegra_periph_reset_deassert(clk); clk_put(clk); } ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), GFP_KERNEL); if (!ahub) { dev_err(&pdev->dev, "Can't allocate tegra30_ahub\n"); ret = -ENOMEM; goto err; } dev_set_drvdata(&pdev->dev, ahub); ahub->dev = &pdev->dev; ahub->clk_d_audio = clk_get(&pdev->dev, "d_audio"); if (IS_ERR(ahub->clk_d_audio)) { dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n"); ret = PTR_ERR(ahub->clk_d_audio); goto err; } ahub->clk_apbif = clk_get(&pdev->dev, "apbif"); if (IS_ERR(ahub->clk_apbif)) { dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n"); ret = PTR_ERR(ahub->clk_apbif); goto err_clk_put_d_audio; } if (of_property_read_u32_array(pdev->dev.of_node, "nvidia,dma-request-selector", of_dma, 2) < 0) { dev_err(&pdev->dev, "Missing property nvidia,dma-request-selector\n"); ret = -ENODEV; goto err_clk_put_d_audio; } ahub->dma_sel = of_dma[1]; res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res0) { dev_err(&pdev->dev, "No apbif memory resource\n"); ret = -ENODEV; goto err_clk_put_apbif; } region = devm_request_mem_region(&pdev->dev, res0->start, resource_size(res0), DRV_NAME); if (!region) { dev_err(&pdev->dev, "request region apbif failed\n"); ret = -EBUSY; goto err_clk_put_apbif; } ahub->apbif_addr = res0->start; regs_apbif = devm_ioremap(&pdev->dev, res0->start, resource_size(res0)); if (!regs_apbif) { dev_err(&pdev->dev, "ioremap apbif failed\n"); ret = -ENOMEM; goto err_clk_put_apbif; } ahub->regmap_apbif = devm_regmap_init_mmio(&pdev->dev, regs_apbif, &tegra30_ahub_apbif_regmap_config); if (IS_ERR(ahub->regmap_apbif)) { dev_err(&pdev->dev, "apbif regmap init failed\n"); ret = PTR_ERR(ahub->regmap_apbif); goto err_clk_put_apbif; } regcache_cache_only(ahub->regmap_apbif, true); res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res1) { dev_err(&pdev->dev, "No ahub memory resource\n"); ret = -ENODEV; goto err_clk_put_apbif; } region = devm_request_mem_region(&pdev->dev, res1->start, resource_size(res1), DRV_NAME); if (!region) { dev_err(&pdev->dev, "request region ahub failed\n"); ret = -EBUSY; goto err_clk_put_apbif; } regs_ahub = devm_ioremap(&pdev->dev, res1->start, resource_size(res1)); if (!regs_ahub) { dev_err(&pdev->dev, "ioremap ahub failed\n"); ret = -ENOMEM; goto err_clk_put_apbif; } ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub, &tegra30_ahub_ahub_regmap_config); if (IS_ERR(ahub->regmap_ahub)) { dev_err(&pdev->dev, "ahub regmap init failed\n"); ret = PTR_ERR(ahub->regmap_ahub); goto err_clk_put_apbif; } regcache_cache_only(ahub->regmap_ahub, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra30_ahub_runtime_resume(&pdev->dev); if (ret) goto err_pm_disable; } of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); err_clk_put_apbif: clk_put(ahub->clk_apbif); err_clk_put_d_audio: clk_put(ahub->clk_d_audio); ahub = NULL; err: return ret; }
int twl6040_power(struct twl6040 *twl6040, int on) { int ret = 0; mutex_lock(&twl6040->mutex); if (on) { /* already powered-up */ if (twl6040->power_count++) goto out; ret = clk_prepare_enable(twl6040->clk32k); if (ret) { twl6040->power_count = 0; goto out; } /* Allow writes to the chip */ regcache_cache_only(twl6040->regmap, false); if (gpio_is_valid(twl6040->audpwron)) { /* use automatic power-up sequence */ ret = twl6040_power_up_automatic(twl6040); if (ret) { clk_disable_unprepare(twl6040->clk32k); twl6040->power_count = 0; goto out; } } else { /* use manual power-up sequence */ ret = twl6040_power_up_manual(twl6040); if (ret) { clk_disable_unprepare(twl6040->clk32k); twl6040->power_count = 0; goto out; } } /* * Register access can produce errors after power-up unless we * wait at least 8ms based on measurements on duovero. */ usleep_range(10000, 12000); /* Sync with the HW */ ret = regcache_sync(twl6040->regmap); if (ret) { dev_err(twl6040->dev, "Failed to sync with the HW: %i\n", ret); goto out; } /* Default PLL configuration after power up */ twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; twl6040->sysclk_rate = 19200000; } else { /* already powered-down */ if (!twl6040->power_count) { dev_err(twl6040->dev, "device is already powered-off\n"); ret = -EPERM; goto out; } if (--twl6040->power_count) goto out; if (gpio_is_valid(twl6040->audpwron)) { /* use AUDPWRON line */ gpio_set_value(twl6040->audpwron, 0); /* power-down sequence latency */ usleep_range(500, 700); } else { /* use manual power-down sequence */ twl6040_power_down_manual(twl6040); } /* Set regmap to cache only and mark it as dirty */ regcache_cache_only(twl6040->regmap, true); regcache_mark_dirty(twl6040->regmap); twl6040->sysclk_rate = 0; if (twl6040->pll == TWL6040_SYSCLK_SEL_HPPLL) { clk_disable_unprepare(twl6040->mclk); twl6040->mclk_rate = 0; } clk_disable_unprepare(twl6040->clk32k); } out: mutex_unlock(&twl6040->mutex); return ret; }
static int sta32x_probe(struct snd_soc_codec *codec) { struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); int i, ret = 0, thermal = 0; sta32x->codec = codec; sta32x->pdata = dev_get_platdata(codec->dev); ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); if (ret != 0) { dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); return ret; } /* Chip documentation explicitly requires that the reset values * of reserved register bits are left untouched. * Write the register default value to cache for reserved registers, * so the write to the these registers are suppressed by the cache * restore code when it skips writes of default registers. */ regcache_cache_only(sta32x->regmap, true); snd_soc_write(codec, STA32X_CONFC, 0xc2); snd_soc_write(codec, STA32X_CONFE, 0xc2); snd_soc_write(codec, STA32X_CONFF, 0x5c); snd_soc_write(codec, STA32X_MMUTE, 0x10); snd_soc_write(codec, STA32X_AUTO1, 0x60); snd_soc_write(codec, STA32X_AUTO3, 0x00); snd_soc_write(codec, STA32X_C3CFG, 0x40); regcache_cache_only(sta32x->regmap, false); /* set thermal warning adjustment and recovery */ if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE)) thermal |= STA32X_CONFA_TWAB; if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE)) thermal |= STA32X_CONFA_TWRB; snd_soc_update_bits(codec, STA32X_CONFA, STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, thermal); /* select output configuration */ snd_soc_update_bits(codec, STA32X_CONFF, STA32X_CONFF_OCFG_MASK, sta32x->pdata->output_conf << STA32X_CONFF_OCFG_SHIFT); /* channel to output mapping */ snd_soc_update_bits(codec, STA32X_C1CFG, STA32X_CxCFG_OM_MASK, sta32x->pdata->ch1_output_mapping << STA32X_CxCFG_OM_SHIFT); snd_soc_update_bits(codec, STA32X_C2CFG, STA32X_CxCFG_OM_MASK, sta32x->pdata->ch2_output_mapping << STA32X_CxCFG_OM_SHIFT); snd_soc_update_bits(codec, STA32X_C3CFG, STA32X_CxCFG_OM_MASK, sta32x->pdata->ch3_output_mapping << STA32X_CxCFG_OM_SHIFT); /* initialize coefficient shadow RAM with reset values */ for (i = 4; i <= 49; i += 5) sta32x->coef_shadow[i] = 0x400000; for (i = 50; i <= 54; i++) sta32x->coef_shadow[i] = 0x7fffff; sta32x->coef_shadow[55] = 0x5a9df7; sta32x->coef_shadow[56] = 0x7fffff; sta32x->coef_shadow[59] = 0x7fffff; sta32x->coef_shadow[60] = 0x400000; sta32x->coef_shadow[61] = 0x400000; if (sta32x->pdata->needs_esd_watchdog) INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog); sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); return 0; }
static int twl6040_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device_node *node = client->dev.of_node; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int irq, ret, children = 0; if (!node) { dev_err(&client->dev, "of node is missing\n"); return -EINVAL; } /* In order to operate correctly we need valid interrupt config */ if (!client->irq) { dev_err(&client->dev, "Invalid IRQ configuration\n"); return -EINVAL; } twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), GFP_KERNEL); if (!twl6040) return -ENOMEM; twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config); if (IS_ERR(twl6040->regmap)) return PTR_ERR(twl6040->regmap); i2c_set_clientdata(client, twl6040); twl6040->clk32k = devm_clk_get(&client->dev, "clk32k"); if (IS_ERR(twl6040->clk32k)) { if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_dbg(&client->dev, "clk32k is not handled\n"); twl6040->clk32k = NULL; } twl6040->mclk = devm_clk_get(&client->dev, "mclk"); if (IS_ERR(twl6040->mclk)) { if (PTR_ERR(twl6040->mclk) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_dbg(&client->dev, "mclk is not handled\n"); twl6040->mclk = NULL; } twl6040->supplies[0].supply = "vio"; twl6040->supplies[1].supply = "v2v1"; ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, twl6040->supplies); if (ret != 0) { dev_err(&client->dev, "Failed to get supplies: %d\n", ret); return ret; } ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies); if (ret != 0) { dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); return ret; } twl6040->dev = &client->dev; twl6040->irq = client->irq; mutex_init(&twl6040->mutex); init_completion(&twl6040->ready); regmap_register_patch(twl6040->regmap, twl6040_patch, ARRAY_SIZE(twl6040_patch)); twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); if (twl6040->rev < 0) { dev_err(&client->dev, "Failed to read revision register: %d\n", twl6040->rev); ret = twl6040->rev; goto gpio_err; } /* ERRATA: Automatic power-up is not possible in ES1.0 */ if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) twl6040->audpwron = of_get_named_gpio(node, "ti,audpwron-gpio", 0); else twl6040->audpwron = -EINVAL; if (gpio_is_valid(twl6040->audpwron)) { ret = devm_gpio_request_one(&client->dev, twl6040->audpwron, GPIOF_OUT_INIT_LOW, "audpwron"); if (ret) goto gpio_err; /* Clear any pending interrupt */ twl6040_reg_read(twl6040, TWL6040_REG_INTID); } ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, 0, &twl6040_irq_chip, &twl6040->irq_data); if (ret < 0) goto gpio_err; twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_READY); twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_TH); ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL, twl6040_readyint_handler, IRQF_ONESHOT, "twl6040_irq_ready", twl6040); if (ret) { dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); goto readyirq_err; } ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL, twl6040_thint_handler, IRQF_ONESHOT, "twl6040_irq_th", twl6040); if (ret) { dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret); goto readyirq_err; } /* * The main functionality of twl6040 to provide audio on OMAP4+ systems. * We can add the ASoC codec child whenever this driver has been loaded. */ irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG); cell = &twl6040->cells[children]; cell->name = "twl6040-codec"; twl6040_codec_rsrc[0].start = irq; twl6040_codec_rsrc[0].end = irq; cell->resources = twl6040_codec_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); children++; /* Vibra input driver support */ if (twl6040_has_vibra(node)) { irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB); cell = &twl6040->cells[children]; cell->name = "twl6040-vibra"; twl6040_vibra_rsrc[0].start = irq; twl6040_vibra_rsrc[0].end = irq; cell->resources = twl6040_vibra_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); children++; } /* GPO support */ cell = &twl6040->cells[children]; cell->name = "twl6040-gpo"; children++; /* PDM clock support */ cell = &twl6040->cells[children]; cell->name = "twl6040-pdmclk"; children++; /* The chip is powered down so mark regmap to cache only and dirty */ regcache_cache_only(twl6040->regmap, true); regcache_mark_dirty(twl6040->regmap); ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, NULL, 0, NULL); if (ret) goto readyirq_err; return 0; readyirq_err: regmap_del_irq_chip(twl6040->irq, twl6040->irq_data); gpio_err: regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); return ret; }
static int tegra30_i2s_platform_probe(struct platform_device *pdev) { struct tegra30_i2s *i2s; u32 cif_ids[2]; struct resource *mem, *memregion; void __iomem *regs; int ret; i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL); if (!i2s) { dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n"); ret = -ENOMEM; goto err; } dev_set_drvdata(&pdev->dev, i2s); i2s->dai = tegra30_i2s_dai_template; i2s->dai.name = dev_name(&pdev->dev); ret = of_property_read_u32_array(pdev->dev.of_node, "nvidia,ahub-cif-ids", cif_ids, ARRAY_SIZE(cif_ids)); if (ret < 0) goto err; i2s->playback_i2s_cif = cif_ids[0]; i2s->capture_i2s_cif = cif_ids[1]; i2s->clk_i2s = clk_get(&pdev->dev, NULL); if (IS_ERR(i2s->clk_i2s)) { dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); ret = PTR_ERR(i2s->clk_i2s); goto err; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "No memory resource\n"); ret = -ENODEV; goto err_clk_put; } memregion = devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), DRV_NAME); if (!memregion) { dev_err(&pdev->dev, "Memory region already claimed\n"); ret = -EBUSY; goto err_clk_put; } regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto err_clk_put; } i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &tegra30_i2s_regmap_config); if (IS_ERR(i2s->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); ret = PTR_ERR(i2s->regmap); goto err_clk_put; } regcache_cache_only(i2s->regmap, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra30_i2s_runtime_resume(&pdev->dev); if (ret) goto err_pm_disable; } ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; goto err_suspend; } ret = tegra_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); goto err_unregister_dai; } return 0; err_unregister_dai: snd_soc_unregister_dai(&pdev->dev); err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) tegra30_i2s_runtime_suspend(&pdev->dev); err_pm_disable: pm_runtime_disable(&pdev->dev); err_clk_put: clk_put(i2s->clk_i2s); err: return ret; }
static int max98925_suspend(struct device *dev) { regcache_cache_only(max98925_data->regmapL, true); return 0; }