static int imx_gpcv2_probe(struct platform_device *pdev) { int ret; struct regulator *pcie_reg, *mipi_reg, *usb_hsic_reg; if (cpu_is_imx7d()) { pcie_reg = devm_regulator_get(&pdev->dev, "pcie-phy"); if (IS_ERR(pcie_reg)) { ret = PTR_ERR(pcie_reg); dev_info(&pdev->dev, "pcie regulator not ready.\n"); return ret; } nb_pcie.notifier_call = &imx_pcie_regulator_notify; ret = regulator_register_notifier(pcie_reg, &nb_pcie); if (ret) { dev_err(&pdev->dev, "pcie regulator notifier request failed\n"); return ret; } mipi_reg = devm_regulator_get(&pdev->dev, "mipi-phy"); if (IS_ERR(mipi_reg)) { ret = PTR_ERR(mipi_reg); dev_info(&pdev->dev, "mipi regulator not ready.\n"); return ret; } nb_mipi.notifier_call = &imx_mipi_regulator_notify; ret = regulator_register_notifier(mipi_reg, &nb_mipi); if (ret) { dev_err(&pdev->dev, "mipi regulator notifier request failed.\n"); return ret; } usb_hsic_reg = devm_regulator_get(&pdev->dev, "vcc"); if (IS_ERR(usb_hsic_reg)) { ret = PTR_ERR(usb_hsic_reg); dev_err(&pdev->dev, "usb hsic regulator not ready.\n"); return ret; } nb_usb_hsic.notifier_call = &imx_usb_hsic_regulator_notify; ret = regulator_register_notifier(usb_hsic_reg, &nb_usb_hsic); if (ret) { dev_err(&pdev->dev, "usb hsic regulator notifier request failed\n"); return ret; } } return 0; }
static int wm8770_spi_probe(struct spi_device *spi) { struct wm8770_priv *wm8770; int ret, i; wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv), GFP_KERNEL); if (!wm8770) return -ENOMEM; for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) wm8770->supplies[i].supply = wm8770_supply_names[i]; ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8770->supplies), wm8770->supplies); if (ret) { dev_err(&spi->dev, "Failed to request supplies: %d\n", ret); return ret; } wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; /* This should really be moved into the regulator core */ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { ret = regulator_register_notifier(wm8770->supplies[i].consumer, &wm8770->disable_nb[i]); if (ret) { dev_err(&spi->dev, "Failed to register regulator notifier: %d\n", ret); } } wm8770->regmap = devm_regmap_init_spi(spi, &wm8770_regmap); if (IS_ERR(wm8770->regmap)) return PTR_ERR(wm8770->regmap); spi_set_drvdata(spi, wm8770); ret = devm_snd_soc_register_component(&spi->dev, &soc_component_dev_wm8770, &wm8770_dai, 1); return ret; }
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; ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } 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 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); codec->control_data = aic31xx->regmap; aic31xx->codec = codec; ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "snd_soc_codec_set_cache_io failed %d\n", ret); return ret; } 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; } } /* off, with power on */ aic31xx_set_bias_level(codec, SND_SOC_BIAS_STANDBY); aic31xx_add_controls(codec); aic31xx_add_widgets(codec); return ret; }
static int __init pwr_detect_cell_init_one( struct device *dev, struct pwr_detect_cell *cell, u32 *disabled_mask) { int ret; struct regulator *regulator = regulator_get(dev, cell->reg_id); if (IS_ERR(regulator)) return PTR_ERR(regulator); cell->regulator_nb.notifier_call = pwrdet_notify_cb; ret = regulator_register_notifier(regulator, &cell->regulator_nb); if (ret) { cell->regulator_nb.notifier_call = NULL; regulator_put(regulator); return ret; } if (!regulator_is_enabled(regulator)) *disabled_mask |= cell->pwrio_mask; regulator_put(regulator); return 0; }
int pcm512x_probe(struct device *dev, struct regmap *regmap) { struct pcm512x_priv *pcm512x; int i, ret; pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL); if (!pcm512x) return -ENOMEM; dev_set_drvdata(dev, pcm512x); pcm512x->regmap = regmap; for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) pcm512x->supplies[i].supply = pcm512x_supply_names[i]; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); if (ret != 0) { dev_err(dev, "Failed to get supplies: %d\n", ret); return ret; } pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0; pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1; pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2; for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) { ret = regulator_register_notifier(pcm512x->supplies[i].consumer, &pcm512x->supply_nb[i]); if (ret != 0) { dev_err(dev, "Failed to register regulator notifier: %d\n", 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; } /* Reset the device, verifying I/O in the process for I2C */ ret = regmap_write(regmap, PCM512x_RESET, PCM512x_RSTM | PCM512x_RSTR); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err; } ret = regmap_write(regmap, PCM512x_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err; } pcm512x->sclk = devm_clk_get(dev, NULL); if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) return -EPROBE_DEFER; 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; } } /* Default to standby mode */ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, PCM512x_RQST, PCM512x_RQST); if (ret != 0) { dev_err(dev, "Failed to request standby: %d\n", ret); goto err_clk; } pm_runtime_set_active(dev); pm_runtime_enable(dev); pm_runtime_idle(dev); #ifdef CONFIG_OF if (dev->of_node) { const struct device_node *np = dev->of_node; u32 val; if (of_property_read_u32(np, "pll-in", &val) >= 0) { if (val > 6) { dev_err(dev, "Invalid pll-in\n"); ret = -EINVAL; goto err_clk; } pcm512x->pll_in = val; } if (of_property_read_u32(np, "pll-out", &val) >= 0) { if (val > 6) { dev_err(dev, "Invalid pll-out\n"); ret = -EINVAL; goto err_clk; } pcm512x->pll_out = val; } if (!pcm512x->pll_in != !pcm512x->pll_out) { dev_err(dev, "Error: both pll-in and pll-out, or none\n"); ret = -EINVAL; goto err_clk; } if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) { dev_err(dev, "Error: pll-in == pll-out\n"); ret = -EINVAL; goto err_clk; } } #endif ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, &pcm512x_dai, 1); if (ret != 0) { dev_err(dev, "Failed to register CODEC: %d\n", ret); goto err_pm; } return 0; err_pm: pm_runtime_disable(dev); err_clk: if (!IS_ERR(pcm512x->sclk)) clk_disable_unprepare(pcm512x->sclk); err: regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); return ret; }
static int __devinit sht15_probe(struct platform_device *pdev) { int ret = 0; struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { ret = -ENOMEM; dev_err(&pdev->dev, "kzalloc failed"); goto error_ret; } INIT_WORK(&data->read_work, sht15_bh_read_data); INIT_WORK(&data->update_supply_work, sht15_update_voltage); platform_set_drvdata(pdev, data); mutex_init(&data->read_lock); data->dev = &pdev->dev; init_waitqueue_head(&data->wait_queue); if (pdev->dev.platform_data == NULL) { dev_err(&pdev->dev, "no platform data supplied"); goto err_free_data; } data->pdata = pdev->dev.platform_data; data->supply_uV = data->pdata->supply_mv*1000; /* If a regulator is available, query what the supply voltage actually is!*/ data->reg = regulator_get(data->dev, "vcc"); if (!IS_ERR(data->reg)) { int voltage; voltage = regulator_get_voltage(data->reg); if (voltage) data->supply_uV = voltage; regulator_enable(data->reg); /* setup a notifier block to update this if another device * causes the voltage to change */ data->nb.notifier_call = &sht15_invalidate_voltage; ret = regulator_register_notifier(data->reg, &data->nb); } /* Try requesting the GPIOs */ ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); if (ret) { dev_err(&pdev->dev, "gpio request failed"); goto err_free_data; } gpio_direction_output(data->pdata->gpio_sck, 0); ret = gpio_request(data->pdata->gpio_data, "SHT15 data"); if (ret) { dev_err(&pdev->dev, "gpio request failed"); goto err_release_gpio_sck; } ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); if (ret) { dev_err(&pdev->dev, "sysfs create failed"); goto err_release_gpio_data; } ret = request_irq(gpio_to_irq(data->pdata->gpio_data), sht15_interrupt_fired, IRQF_TRIGGER_FALLING, "sht15 data", data); if (ret) { dev_err(&pdev->dev, "failed to get irq for data line"); goto err_release_gpio_data; } disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); sht15_connection_reset(data); sht15_send_cmd(data, 0x1E); data->hwmon_dev = hwmon_device_register(data->dev); if (IS_ERR(data->hwmon_dev)) { ret = PTR_ERR(data->hwmon_dev); goto err_release_irq; } return 0; err_release_irq: free_irq(gpio_to_irq(data->pdata->gpio_data), data); err_release_gpio_data: gpio_free(data->pdata->gpio_data); err_release_gpio_sck: gpio_free(data->pdata->gpio_sck); err_free_data: kfree(data); error_ret: return ret; }
static int __devinit hi_mci_probe(struct platform_device *pdev) { struct mshci_host *ms_host = NULL; struct himci_host *hi_host = NULL; struct hisik3_mmc_platform_data *plat = NULL; struct resource *memres = NULL; int ret = 0, irq; int err; bool RetVal = 0; unsigned long flags; unsigned int sdcard_frequency = 0; #ifdef CONFIG_MACH_HI6620OEM if(1 == pdev->id) { raw_mmc_turn_on(); } #endif himci_trace(HIMCI_TRACE_GEN_API, "++"); himci_assert(pdev); plat = pdev->dev.platform_data; himci_trace(HIMCI_TRACE_SIGNIFICANT, "id:%d", pdev->id); /*通过读取硬件配置项,或者sdcard时钟配置,只需要SD卡流程走,走一遍*/ #ifdef CONFIG_MACH_HI6620OEM if(1 == pdev->id) { RetVal = get_hw_config_int("sd_card/sdcard_frequency", &sdcard_frequency, NULL); printk("hsad: sd_card/sdcard_frequency = %d, RetVal = %d\n", sdcard_frequency, RetVal); /*读取失败,配置默认值*/ if (RetVal == false) { printk(KERN_ERR "get board type failed.\n"); g_sdcard_frequency = 90; } /*如果获取配置值异常,则配置默认值*/ if ((sdcard_frequency != 100)&&(sdcard_frequency != 90)) { printk(KERN_ERR "sdcard_frequency %x is error.\n",sdcard_frequency); g_sdcard_frequency = 90; } g_sdcard_frequency = sdcard_frequency; } #endif /* 获取自己定义的数据 */ if (!plat) { himci_error("Platform data not available"); return -ENOENT; } if(0 == pdev->id) { sema_init(&sem_to_rfile_sync_req,0); } /*创建硬件信号量IPC_SEM_EMMC*/ if (0 == pdev->id) { mutex_lock(&emmc_mutex); emmc_sem_flag = 1; mutex_unlock(&emmc_mutex); } irq = platform_get_irq(pdev, 0); memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); if ((!irq) || (!memres)) { himci_error("resource error"); ret = -ENOENT; goto err_resource_get; } himci_trace(HIMCI_TRACE_SIGNIFICANT, "irq:%d,start:0x%x,size:0x%x", irq, \ memres->start, resource_size(memres)); ms_host = mshci_alloc_host(&pdev->dev, sizeof(struct himci_host)); if (IS_ERR(ms_host)) { himci_error("mshci_alloc_host() failed\n"); ret = PTR_ERR(ms_host); goto err_resource_get; } hi_host = mshci_priv(ms_host); hi_host->ms_host = ms_host; hi_host->pdev = pdev; hi_host->dev = &pdev->dev; hi_host->plat = plat; platform_set_drvdata(pdev, ms_host); /* MMC IP rstdis */ if (plat->rstdis_mmc){ ret = plat->rstdis_mmc(); if ( ret < 0 ){ goto err_resource_get; } } /* set emmc clk */ hi_host->pclk = clk_get(&pdev->dev, plat->clk_mmc_low); /* work clk */ if (IS_ERR(hi_host->pclk)) { himci_error("clk_get clk_mmc_low fail!"); ret = PTR_ERR(hi_host->pclk); goto err_io_clk; } hi_host->clk_mmc_high= clk_get(&pdev->dev, plat->clk_mmc_high); /* highclk used for tuning */ if (IS_ERR(hi_host->clk_mmc_high)) { himci_error("clk_get clk_mmc_high fail!"); ret = PTR_ERR(hi_host->clk_mmc_high); goto err_io_clk; } ms_host->pclk = NULL; ms_host->clk_ref_counter = CLK_DISABLED; ms_host->clk_mmc_high = NULL; ms_host->pclk = hi_host->pclk; ms_host->clk_mmc_high = hi_host->clk_mmc_high; if (ret) { himci_error("failed to clk_set_rate"); } if(ms_host->clk_ref_counter == CLK_DISABLED){ ret = clk_enable(hi_host->pclk); ms_host->clk_ref_counter = CLK_ENABLED; if (ret) { himci_error("clk_enable failed"); ret = -ENOENT; goto err_clk_ops; } } ms_host->ioaddr = ioremap_nocache(memres->start, resource_size(memres)); if (!ms_host->ioaddr) { himci_error("ioremap_nocache failed"); ret = -ENXIO; goto err_req_regs; } ms_host->hw_name = "hisi_hi6620_mmc"; ms_host->hw_mmc_id = hi_host->pdev->id; ms_host->ops = &mshci_hi_ops; ms_host->quirks = 0; ms_host->irq = irq; /* Setup quirks for the controller */ if (plat->quirks) { ms_host->quirks |= plat->quirks; } if (plat->caps & MMC_CAP_CLOCK_GATING) { /* there is no reason not to use interral clock gating */ ms_host->mmc->caps |= plat->caps; ms_host->mmc->caps |= MMC_CAP_CLOCK_GATING; ms_host->clock_gate = 1; } else { ms_host->mmc->caps |= plat->caps; ms_host->clock_gate = 0; } ms_host->mmc->caps2 = plat->caps2; /* sandisk card need clock longer than spec ask */ /* sdcard also disable ip clock gate c00261379*/ if (ms_host->hw_mmc_id == 0 || ms_host->hw_mmc_id == 1) ms_host->clock_gate = 0; if (plat->ocr_mask) ms_host->mmc->ocr_avail |= plat->ocr_mask; #ifdef CONFIG_MACH_HI6620OEM if (plat->iomux_name){ hi_host->piomux_block = iomux_get_block(plat->iomux_name); hi_host->pblock_config = iomux_get_blockconfig(plat->iomux_name); } /* todo requlator */ if (plat->reg_name_ldo) { himci_trace(HIMCI_TRACE_SIGNIFICANT, "devname : %s, regname: %s", dev_name(hi_host->dev), plat->reg_name_ldo); hi_host->vcc_ldo = regulator_get(hi_host->dev, plat->reg_name_ldo); if (!IS_ERR(hi_host->vcc_ldo)) { /* * Setup a notifier block to update this if another device * causes the voltage to change */ hi_host->nb.notifier_call = &mshci_hi_disable_voltage; ret = regulator_register_notifier(hi_host->vcc_ldo, &hi_host->nb); if (ret) { dev_err(&pdev->dev, "regulator notifier request failed\n"); } } else { dev_err(&pdev->dev, "regulator_get() failed\n"); hi_host->vcc_ldo = NULL; } } if (plat->reg_name_lvs) { himci_trace(HIMCI_TRACE_SIGNIFICANT, "devname : %s, regname: %s", dev_name(hi_host->dev), plat->reg_name_lvs); hi_host->vcc_lvs = regulator_get(hi_host->dev, plat->reg_name_lvs); if (!IS_ERR(hi_host->vcc_lvs)) { /* * Setup a notifier block to update this if another device * causes the voltage to change */ hi_host->nb.notifier_call = &mshci_hi_disable_voltage; ret = regulator_register_notifier(hi_host->vcc_lvs, &hi_host->nb); if (ret) { dev_err(&pdev->dev, "regulator notifier request failed\n"); } } else { dev_err(&pdev->dev, "regulator_get() failed\n"); hi_host->vcc_lvs = NULL; } } hi_host->ocp_flag = 0; if (plat->signal_reg_name) { himci_trace(HIMCI_TRACE_SIGNIFICANT, "devname : %s, signal regname: %s", dev_name(hi_host->dev), plat->signal_reg_name); hi_host->signal_vcc = regulator_get(hi_host->dev, plat->signal_reg_name); if (IS_ERR(hi_host->signal_vcc)) { dev_err(&pdev->dev, "regulator_get() failed\n"); hi_host->signal_vcc = NULL; } } #endif if( (1 == pdev->id)&&( (ms_host->quirks & MSHCI_QUIRK_CBP_DETECTION) == 0)) { ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER); if (ret) { himci_error("failed to blockmux_set"); } mshci_sd_lowpower(); if (hi_host->vcc_lvs){ ret = regulator_enable(hi_host->vcc_lvs); if (ret) { himci_error("failed to regulator_enable LDO7"); } ret = regulator_disable(hi_host->vcc_lvs); if (ret) { himci_error("failed to regulator_disable LDO7"); } } udelay(30); if (hi_host->signal_vcc){ ret = regulator_enable(hi_host->signal_vcc); if (ret) { himci_error("failed to regulator_enable LDO22"); } ret = regulator_disable(hi_host->signal_vcc); if (ret) { himci_error("failed to regulator_disable LDO22"); } } }else {/*for cbp*/ ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL); if (ret) { himci_error("failed to blockmux_set"); } if (hi_host->vcc_lvs){ ret = regulator_enable(hi_host->vcc_lvs); if (ret) { himci_error("failed to regulator_enable LDO7"); } } udelay(30); if (hi_host->signal_vcc){ ret = regulator_enable(hi_host->signal_vcc); if (ret) { himci_error("failed to regulator_enable LDO22"); } ret = regulator_disable(hi_host->signal_vcc); if (ret) { himci_error("failed to regulator_disable LDO22"); } } } hi_host->old_sig_voltage = plat->default_signal_voltage; hi_host->old_timing = MMC_TIMING_UHS_DDR50; hi_host->timing_config = plat->timing_config; hi_host->allow_switch_signal_voltage = plat->allow_switch_signal_voltage; hi_host->suspend_timing_config = plat->suspend_timing_config; if (ms_host->quirks & MSHCI_QUIRK_WLAN_DETECTION) { ms_host->flags |= MSHCI_DEVICE_DEAD; ms_host->flags |= MMC_PM_KEEP_POWER; ms_host->mmc->pm_caps |= MMC_PM_KEEP_POWER; } ret = mshci_add_host(ms_host); if (ret) { dev_err(&pdev->dev, "mshci_add_host() failed\n"); goto err_add_host; } if (ms_host->quirks & MSHCI_QUIRK_WLAN_DETECTION) { ms_host->flags |= MSHCI_DEVICE_DEAD; ms_host->flags |= MMC_PM_KEEP_POWER; ms_host->mmc->pm_caps |= MMC_PM_KEEP_POWER; if (plat->ext_cd_init) plat->ext_cd_init(&mshci_hi_notify_change); plat->set_power = mshci_hi_sdio_set_power; } if( (1 == pdev->id)&&( (ms_host->quirks & MSHCI_QUIRK_CBP_DETECTION) != 0)) { ms_host->flags |= MMC_PM_KEEP_POWER; ms_host->mmc->pm_caps |= MMC_PM_KEEP_POWER; } if (ms_host->quirks & MSHCI_QUIRK_EXTERNAL_CARD_DETECTION) { err = gpio_request_one(plat->cd_gpio, GPIOF_IN, "ESDHC_CD"); if (err) { dev_warn(mmc_dev(ms_host->mmc), "no card-detect pin available!\n"); goto no_card_detect_pin; } /*SD_INT_FIX_suspend DTS:2013082704916 modifier: y00241633*/ err = request_irq(gpio_to_irq(plat->cd_gpio), mshci_hi_card_detect_gpio, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, mmc_hostname(ms_host->mmc), ms_host); if (err) { dev_warn(mmc_dev(ms_host->mmc), "request gpio irq error\n"); goto no_card_detect_irq; } if ( plat->sw_gpio ){ /* only sft has this gpio */ err = gpio_request_one(plat->sw_gpio, 0, "ESDHC_POWER_SWITCH"); if (err) { dev_warn(mmc_dev(ms_host->mmc), "no card-power-switch pin available!\n"); goto no_card_power_switch_pin; } /*控制I/O口电平 1V8 or 3V3*/ gpio_direction_output(plat->sw_gpio, 1); } } return 0; no_card_power_switch_pin: plat->sw_gpio = err; no_card_detect_irq: gpio_free(plat->cd_gpio); no_card_detect_pin: plat->cd_gpio = err; err_add_host: iounmap(ms_host->ioaddr); ms_host->ioaddr = NULL; err_req_regs: spin_lock_irqsave(&ms_host->lock, flags); if(ms_host->clk_ref_counter == CLK_ENABLED){ clk_disable(hi_host->pclk); ms_host->clk_ref_counter = CLK_DISABLED; } spin_unlock_irqrestore(&ms_host->lock, flags); err_clk_ops: clk_put(hi_host->clk_mmc_high); clk_put(hi_host->pclk); err_io_clk: mshci_free_host(ms_host); err_resource_get: return ret; }
static int wm8770_probe(struct snd_soc_codec *codec) { struct wm8770_priv *wm8770; int ret; int i; wm8770 = snd_soc_codec_get_drvdata(codec); wm8770->codec = codec; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) wm8770->supplies[i].supply = wm8770_supply_names[i]; ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies), wm8770->supplies); if (ret) { dev_err(codec->dev, "Failed to request supplies: %d\n", ret); return ret; } wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; /* This should really be moved into the regulator core */ for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { ret = regulator_register_notifier(wm8770->supplies[i].consumer, &wm8770->disable_nb[i]); if (ret) { dev_err(codec->dev, "Failed to register regulator notifier: %d\n", ret); } } ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); if (ret) { dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); goto err_reg_get; } ret = wm8770_reset(codec); if (ret < 0) { dev_err(codec->dev, "Failed to issue reset: %d\n", ret); goto err_reg_enable; } wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* latch the volume update bits */ snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100); /* mute all DACs */ snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); snd_soc_add_codec_controls(codec, wm8770_snd_controls, ARRAY_SIZE(wm8770_snd_controls)); snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, ARRAY_SIZE(wm8770_dapm_widgets)); snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon, ARRAY_SIZE(wm8770_intercon)); return 0; err_reg_enable: regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); err_reg_get: regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); return ret; }
int pcm512x_probe(struct device *dev, struct regmap *regmap) { struct pcm512x_priv *pcm512x; int i, ret; pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL); if (!pcm512x) return -ENOMEM; dev_set_drvdata(dev, pcm512x); pcm512x->regmap = regmap; for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) pcm512x->supplies[i].supply = pcm512x_supply_names[i]; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); if (ret != 0) { dev_err(dev, "Failed to get supplies: %d\n", ret); return ret; } pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0; pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1; pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2; for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) { ret = regulator_register_notifier(pcm512x->supplies[i].consumer, &pcm512x->supply_nb[i]); if (ret != 0) { dev_err(dev, "Failed to register regulator notifier: %d\n", 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; } /* Reset the device, verifying I/O in the process for I2C */ ret = regmap_write(regmap, PCM512x_RESET, PCM512x_RSTM | PCM512x_RSTR); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err; } ret = regmap_write(regmap, PCM512x_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err; } pcm512x->sclk = devm_clk_get(dev, NULL); if (IS_ERR(pcm512x->sclk)) { if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_info(dev, "No SCLK, using BCLK: %ld\n", PTR_ERR(pcm512x->sclk)); /* Disable reporting of missing SCLK as an error */ regmap_update_bits(regmap, PCM512x_ERROR_DETECT, PCM512x_IDCH, PCM512x_IDCH); /* Switch PLL input to BCLK */ regmap_update_bits(regmap, PCM512x_PLL_REF, PCM512x_SREF, PCM512x_SREF); } else { ret = clk_prepare_enable(pcm512x->sclk); if (ret != 0) { dev_err(dev, "Failed to enable SCLK: %d\n", ret); return ret; } } /* Default to standby mode */ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, PCM512x_RQST, PCM512x_RQST); if (ret != 0) { dev_err(dev, "Failed to request standby: %d\n", ret); goto err_clk; } pm_runtime_set_active(dev); pm_runtime_enable(dev); pm_runtime_idle(dev); ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, &pcm512x_dai, 1); if (ret != 0) { dev_err(dev, "Failed to register CODEC: %d\n", ret); goto err_pm; } return 0; err_pm: pm_runtime_disable(dev); err_clk: if (!IS_ERR(pcm512x->sclk)) clk_disable_unprepare(pcm512x->sclk); err: regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); return ret; }
int dsi_pll_clock_register_20nm(struct platform_device *pdev, struct mdss_pll_resources *pll_res) { int rc; struct dss_vreg *pll_reg; if (!pdev || !pdev->dev.of_node) { pr_err("Invalid input parameters\n"); return -EINVAL; } if (!pll_res || !pll_res->pll_base) { pr_err("Invalid PLL resources\n"); return -EPROBE_DEFER; } /* * Set client data to mux, div and vco clocks. * This needs to be done only for PLL0 since, that is the one in * use. **/ if (!pll_res->index) { dsi0pll_byte_clk_src.priv = pll_res; dsi0pll_pixel_clk_src.priv = pll_res; dsi0pll_bypass_lp_div_mux.priv = pll_res; dsi0pll_indirect_path_div2_clk.priv = pll_res; dsi0pll_ndiv_clk.priv = pll_res; dsi0pll_fixed_hr_oclk2_div_clk.priv = pll_res; dsi0pll_hr_oclk3_div_clk.priv = pll_res; dsi0pll_vco_clk.priv = pll_res; dsi0pll_shadow_byte_clk_src.priv = pll_res; dsi0pll_shadow_pixel_clk_src.priv = pll_res; dsi0pll_shadow_bypass_lp_div_mux.priv = pll_res; dsi0pll_shadow_indirect_path_div2_clk.priv = pll_res; dsi0pll_shadow_ndiv_clk.priv = pll_res; dsi0pll_shadow_fixed_hr_oclk2_div_clk.priv = pll_res; dsi0pll_shadow_hr_oclk3_div_clk.priv = pll_res; dsi0pll_shadow_dsi_vco_clk.priv = pll_res; if (pll_res->pll_en_90_phase) { dsi0pll_vco_clk.min_rate = 1000000000; dsi0pll_vco_clk.max_rate = 2000000000; dsi0pll_shadow_dsi_vco_clk.min_rate = 1000000000; dsi0pll_shadow_dsi_vco_clk.max_rate = 2000000000; pr_debug("%s:Update VCO range: 1GHz-2Ghz", __func__); } } else { dsi1pll_byte_clk_src.priv = pll_res; dsi1pll_pixel_clk_src.priv = pll_res; dsi1pll_bypass_lp_div_mux.priv = pll_res; dsi1pll_indirect_path_div2_clk.priv = pll_res; dsi1pll_ndiv_clk.priv = pll_res; dsi1pll_fixed_hr_oclk2_div_clk.priv = pll_res; dsi1pll_hr_oclk3_div_clk.priv = pll_res; dsi1pll_vco_clk.priv = pll_res; dsi1pll_shadow_byte_clk_src.priv = pll_res; dsi1pll_shadow_pixel_clk_src.priv = pll_res; dsi1pll_shadow_bypass_lp_div_mux.priv = pll_res; dsi1pll_shadow_indirect_path_div2_clk.priv = pll_res; dsi1pll_shadow_ndiv_clk.priv = pll_res; dsi1pll_shadow_fixed_hr_oclk2_div_clk.priv = pll_res; dsi1pll_shadow_hr_oclk3_div_clk.priv = pll_res; dsi1pll_shadow_dsi_vco_clk.priv = pll_res; dsi1pll_vco_dummy_clk.priv = pll_res; if (pll_res->pll_en_90_phase) { dsi1pll_vco_clk.min_rate = 1000000000; dsi1pll_vco_clk.max_rate = 2000000000; dsi1pll_shadow_dsi_vco_clk.min_rate = 1000000000; dsi1pll_shadow_dsi_vco_clk.max_rate = 2000000000; pr_debug("%s:Update VCO range: 1GHz-2Ghz", __func__); } } pll_res->vco_delay = VCO_DELAY_USEC; /* Set clock source operations */ pixel_clk_src_ops = clk_ops_slave_div; pixel_clk_src_ops.prepare = dsi_pll_div_prepare; ndiv_clk_ops = clk_ops_div; ndiv_clk_ops.prepare = dsi_pll_div_prepare; byte_clk_src_ops = clk_ops_div; byte_clk_src_ops.prepare = dsi_pll_div_prepare; bypass_lp_div_mux_clk_ops = clk_ops_gen_mux; bypass_lp_div_mux_clk_ops.prepare = dsi_pll_mux_prepare; clk_ops_gen_mux_dsi = clk_ops_gen_mux; clk_ops_gen_mux_dsi.round_rate = parent_round_rate; clk_ops_gen_mux_dsi.set_rate = parent_set_rate; shadow_pixel_clk_src_ops = clk_ops_slave_div; shadow_pixel_clk_src_ops.prepare = dsi_pll_div_prepare; shadow_byte_clk_src_ops = clk_ops_div; shadow_byte_clk_src_ops.prepare = dsi_pll_div_prepare; if ((pll_res->target_id == MDSS_PLL_TARGET_8994) || (pll_res->target_id == MDSS_PLL_TARGET_8992)) { if (pll_res->index) { rc = of_msm_clock_register(pdev->dev.of_node, dsi1_pllcc_20nm, ARRAY_SIZE(dsi1_pllcc_20nm)); if (rc) { pr_err("Clock register failed\n"); rc = -EPROBE_DEFER; } } else { rc = of_msm_clock_register(pdev->dev.of_node, dsi0_pllcc_20nm, ARRAY_SIZE(dsi0_pllcc_20nm)); if (rc) { pr_err("Clock register failed\n"); rc = -EPROBE_DEFER; } } pll_res->gdsc_cb.notifier_call = dsi_pll_regulator_notifier_call; INIT_WORK(&pll_res->pll_off, dsi_pll_off_work); pll_reg = mdss_pll_get_mp_by_reg_name(pll_res, "gdsc"); if (pll_reg) { pr_debug("Registering for gdsc regulator events\n"); if (regulator_register_notifier(pll_reg->vreg, &(pll_res->gdsc_cb))) pr_err("Regulator notification registration failed!\n"); } } else { pr_err("Invalid target ID\n"); rc = -EINVAL; } if (!rc) pr_info("Registered DSI PLL clocks successfully\n"); return rc; }