static irqreturn_t twl6040_naudint_handler(int irq, void *data) { struct twl6040 *twl6040 = data; u8 intid, status; intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); if (intid & TWL6040_READYINT) complete(&twl6040->ready); if (intid & TWL6040_THINT) { status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS); if (status & TWL6040_TSHUTDET) { dev_warn(&twl6040_dev->dev, "Thermal shutdown, powering-off"); twl6040_power(twl6040, 0); } else { dev_warn(&twl6040_dev->dev, "Leaving thermal shutdown, powering-on"); twl6040_power(twl6040, 1); } } return IRQ_HANDLED; }
static irqreturn_t twl6040_thint_handler(int irq, void *data) { struct twl6040 *twl6040 = data; u8 status; status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS); if (status & TWL6040_TSHUTDET) { dev_warn(twl6040->dev, "Thermal shutdown, powering-off"); twl6040_power(twl6040, 0); } else { dev_warn(twl6040->dev, "Leaving thermal shutdown, powering-on"); twl6040_power(twl6040, 1); } return IRQ_HANDLED; }
static void twl6040_vibra_enable(struct vibra_info *info) { struct twl6040 *twl6040 = info->twl6040; int ret; ret = regulator_bulk_enable(ARRAY_SIZE(info->supplies), info->supplies); if (ret) { dev_err(info->dev, "failed to enable regulators %d\n", ret); return; } twl6040_power(info->twl6040, 1); if (twl6040_get_revid(twl6040) <= TWL6040_REV_ES1_1) { /* * ERRATA: Disable overcurrent protection for at least * 3ms when enabling vibrator drivers to avoid false * overcurrent detection */ twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, TWL6040_VIBENA | TWL6040_VIBCTRL); twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, TWL6040_VIBENA | TWL6040_VIBCTRL); usleep_range(3000, 3500); } twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, TWL6040_VIBENA); twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, TWL6040_VIBENA); info->enabled = true; }
static void twl6040_vibra_enable(struct vibra_info *info) { struct twl6040 *twl6040 = info->twl6040; int ret; ret = regulator_bulk_enable(ARRAY_SIZE(info->supplies), info->supplies); if (ret) { dev_err(info->dev, "failed to enable regulators %d\n", ret); return; } twl6040_power(info->twl6040, 1); if (twl6040_get_revid(twl6040) <= TWL6040_REV_ES1_1) { /* */ twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, TWL6040_VIBENA | TWL6040_VIBCTRL); twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, TWL6040_VIBENA | TWL6040_VIBCTRL); usleep_range(3000, 3500); } twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, TWL6040_VIBENA); twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, TWL6040_VIBENA); info->enabled = true; }
static void omap_abe_mcpdm_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; struct twl6040 *twl6040 = codec->control_data; twl6040_power(twl6040, 0); }
static void omap_abe_dmic_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct omap_abe_data *card_data = snd_soc_card_get_drvdata(card); struct snd_soc_codec *codec = card_data->twl6040_codec; struct twl6040 *twl6040 = codec->control_data; twl6040_power(twl6040, 0); }
static int omap_abe_mcpdm_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_card *card = rtd->card; struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev); struct twl6040 *twl6040 = codec->control_data; int clk_id, freq; int ret; /* twl6040 supplies McPDM PAD_CLKS */ ret = twl6040_power(twl6040, 1); if (ret) { dev_err(card->dev, "failed to enable twl6040\n"); return ret; } clk_id = twl6040_get_clk_id(codec); if (clk_id == TWL6040_SYSCLK_SEL_HPPLL) freq = pdata->mclk_freq; else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL) freq = 32768; else { dev_err(card->dev, "invalid clock\n"); ret = -EINVAL; goto err; } /* set the codec mclk */ ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq, SND_SOC_CLOCK_IN); if (ret) { dev_err(card->dev, "can't set codec system clock\n"); goto err; } return 0; err: twl6040_power(twl6040, 0); return ret; }
int twl6040_disable(struct twl6040_codec *twl6040) { int ret = 0; mutex_lock(&twl6040->mutex); if (!--twl6040->power_count) ret = twl6040_power(twl6040, 0); mutex_unlock(&twl6040->mutex); return ret; }
int twl6040_enable(struct twl6040_codec *twl6040) { int ret = 0; mutex_lock(&twl6040->mutex); if (!twl6040->power_count++) ret = twl6040_power(twl6040, 1); mutex_unlock(&twl6040->mutex); return ret; }
static void twl6040_vibra_disable(struct vibra_info *info) { struct twl6040 *twl6040 = info->twl6040; twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, 0x00); twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, 0x00); twl6040_power(info->twl6040, 0); regulator_bulk_disable(ARRAY_SIZE(info->supplies), info->supplies); info->enabled = false; }
int twl6040_disable(struct twl6040 *twl6040) { int ret = 0; mutex_lock(&twl6040->mutex); WARN(!twl6040->power_count, "TWL6040 is already disabled"); if (!--twl6040->power_count) ret = twl6040_power(twl6040, 0); mutex_unlock(&twl6040->mutex); return ret; }
static int twl6040_remove(struct i2c_client *client) { struct twl6040 *twl6040 = i2c_get_clientdata(client); if (twl6040->power_count) twl6040_power(twl6040, 0); regmap_del_irq_chip(twl6040->irq, twl6040->irq_data); mfd_remove_devices(&client->dev); regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); return 0; }
static int omap_abe_dmic_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct omap_abe_data *card_data = snd_soc_card_get_drvdata(card); struct snd_soc_codec *codec = card_data->twl6040_codec; struct twl6040 *twl6040 = codec->control_data; int ret = 0; /* twl6040 supplies DMic PAD_CLKS */ ret = twl6040_power(twl6040, 1); if (ret) { dev_err(card->dev, "failed to enable twl6040\n"); return ret; } ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS, 19200000, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(card->dev, "can't set DMIC in system clock\n"); goto err; } ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000, SND_SOC_CLOCK_OUT); if (ret < 0) { dev_err(card->dev, "can't set DMIC output clock\n"); goto err; } return 0; err: twl6040_power(twl6040, 0); return ret; }
static int __devexit twl6040_remove(struct platform_device *pdev) { struct twl6040 *twl6040 = platform_get_drvdata(pdev); if (twl6040->power_count) twl6040_power(twl6040, 0); if (gpio_is_valid(twl6040->audpwron)) gpio_free(twl6040->audpwron); free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); twl6040_irq_exit(twl6040); mfd_remove_devices(&pdev->dev); platform_set_drvdata(pdev, NULL); kfree(twl6040); twl6040_dev = NULL; return 0; }