From ace0eb1e91a75b84b1be3d610b79509a5bd94df1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 21 Oct 2014 18:13:46 -0700 Subject: ASoC: rsnd: tidyup debug information when read/write b8c637864a6904a9ba8e0df556d5bdf9f26b2c54 (ASoC: rsnd: use regmap_mmio instead of original regmap bus) added regmap_mmio support on Renesas R-Car sound driver. Then, debug information of register read/write indicates regmap index, not register address. This is a little bit confusable information. This patch tidyup debug message, and added regmap debug hint on comment area. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index f95e7ab..61dee68 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -8,6 +8,17 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +/* + * #define DEBUG + * + * you can also add below in + * ${LINUX}/drivers/base/regmap/regmap.c + * for regmap debug + * + * #define LOG_DEVICE "xxxx.rcar_sound" + */ + #include "rsnd.h" struct rsnd_gen { @@ -67,9 +78,10 @@ u32 rsnd_read(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return 0; - regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); + dev_dbg(dev, "r %s(%d) - %4d : %08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); - dev_dbg(dev, "r %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, val); + regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); return val; } @@ -84,9 +96,10 @@ void rsnd_write(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); + dev_dbg(dev, "w %s(%d) - %4d : %08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); - dev_dbg(dev, "w %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, data); + regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); } void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, @@ -98,11 +111,11 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; + dev_dbg(dev, "b %s(%d) - %4d : %08x/%08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask); + regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), mask, data); - - dev_dbg(dev, "b %s - 0x%04d : %08x/%08x\n", - rsnd_mod_name(mod), reg, data, mask); } #define rsnd_gen_regmap_init(priv, id_size, reg_id, conf) \ -- cgit v0.10.2 From 9960ce97432bdb1defc76ed80ac19e37e8778bc6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 21 Oct 2014 18:13:56 -0700 Subject: ASoC: rsnd: tidyup RSND_DVC_VOLUME_NUM to RSND_DVC_CHANNELS RSND_DVC_VOLUME_NUM means DVC channel number. This patch tidyups this un-understandable naming Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 3f44393..b5f95ad4 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -12,7 +12,7 @@ #define RSND_DVC_NAME_SIZE 16 #define RSND_DVC_VOLUME_MAX 100 -#define RSND_DVC_VOLUME_NUM 2 +#define RSND_DVC_CHANNELS 2 #define DVC_NAME "dvc" @@ -20,8 +20,8 @@ struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - u8 volume[RSND_DVC_VOLUME_NUM]; - u8 mute[RSND_DVC_VOLUME_NUM]; + u8 volume[RSND_DVC_CHANNELS]; + u8 mute[RSND_DVC_CHANNELS]; }; #define rsnd_mod_to_dvc(_mod) \ @@ -37,11 +37,11 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); u32 max = (0x00800000 - 1); - u32 vol[RSND_DVC_VOLUME_NUM]; + u32 vol[RSND_DVC_CHANNELS]; u32 mute = 0; int i; - for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { + for (i = 0; i < RSND_DVC_CHANNELS; i++) { vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; mute |= (!!dvc->mute[i]) << i; } @@ -150,7 +150,7 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); u8 *val = (u8 *)kctrl->private_value; - uinfo->count = RSND_DVC_VOLUME_NUM; + uinfo->count = RSND_DVC_CHANNELS; uinfo->value.integer.min = 0; if (val == dvc->volume) { @@ -170,7 +170,7 @@ static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, u8 *val = (u8 *)kctrl->private_value; int i; - for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) + for (i = 0; i < RSND_DVC_CHANNELS; i++) ucontrol->value.integer.value[i] = val[i]; return 0; @@ -183,7 +183,7 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, u8 *val = (u8 *)kctrl->private_value; int i, change = 0; - for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { + for (i = 0; i < RSND_DVC_CHANNELS; i++) { change |= (ucontrol->value.integer.value[i] != val[i]); val[i] = ucontrol->value.integer.value[i]; } -- cgit v0.10.2 From 92b9a6991b2e3a4ccf5ffc956730d36835d53a79 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 21 Oct 2014 18:14:14 -0700 Subject: ASoC: rsnd: add struct rsnd_dvc_cfg and control DVC settings DVC can control Digital Volume / Mute / Volume Ramp etc, and these uses different max value. Current driver is using fixed max value for each settings. This patch adds new struct rsnd_dvc_cfg, and control these. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index b5f95ad4..deaf0fa 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -11,17 +11,21 @@ #include "rsnd.h" #define RSND_DVC_NAME_SIZE 16 -#define RSND_DVC_VOLUME_MAX 100 #define RSND_DVC_CHANNELS 2 #define DVC_NAME "dvc" +struct rsnd_dvc_cfg { + unsigned int max; + u32 val[RSND_DVC_CHANNELS]; +}; + struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - u8 volume[RSND_DVC_CHANNELS]; - u8 mute[RSND_DVC_CHANNELS]; + struct rsnd_dvc_cfg volume; + struct rsnd_dvc_cfg mute; }; #define rsnd_mod_to_dvc(_mod) \ @@ -36,18 +40,15 @@ struct rsnd_dvc { static void rsnd_dvc_volume_update(struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); - u32 max = (0x00800000 - 1); - u32 vol[RSND_DVC_CHANNELS]; u32 mute = 0; int i; for (i = 0; i < RSND_DVC_CHANNELS; i++) { - vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; - mute |= (!!dvc->mute[i]) << i; + mute |= (!!dvc->mute.val[i]) << i; } - rsnd_mod_write(mod, DVC_VOL0R, vol[0]); - rsnd_mod_write(mod, DVC_VOL1R, vol[1]); + rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]); + rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]); rsnd_mod_write(mod, DVC_ZCMCR, mute); } @@ -146,20 +147,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) { - struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); - u8 *val = (u8 *)kctrl->private_value; + struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; uinfo->count = RSND_DVC_CHANNELS; uinfo->value.integer.min = 0; + uinfo->value.integer.max = cfg->max; - if (val == dvc->volume) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->value.integer.max = RSND_DVC_VOLUME_MAX; - } else { + if (cfg->max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->value.integer.max = 1; - } + else + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; return 0; } @@ -167,11 +164,11 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - u8 *val = (u8 *)kctrl->private_value; + struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i; for (i = 0; i < RSND_DVC_CHANNELS; i++) - ucontrol->value.integer.value[i] = val[i]; + ucontrol->value.integer.value[i] = cfg->val[i]; return 0; } @@ -180,12 +177,12 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - u8 *val = (u8 *)kctrl->private_value; + struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i, change = 0; for (i = 0; i < RSND_DVC_CHANNELS; i++) { - change |= (ucontrol->value.integer.value[i] != val[i]); - val[i] = ucontrol->value.integer.value[i]; + change |= (ucontrol->value.integer.value[i] != cfg->val[i]); + cfg->val[i] = ucontrol->value.integer.value[i]; } if (change) @@ -198,7 +195,7 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd, const unsigned char *name, - u8 *private) + struct rsnd_dvc_cfg *private) { struct snd_card *card = rtd->card->snd_card; struct snd_kcontrol *kctrl; @@ -232,18 +229,20 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, int ret; /* Volume */ + dvc->volume.max = 0x00800000 - 1; ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Playback Volume" : "DVC In Capture Volume", - dvc->volume); + &dvc->volume); if (ret < 0) return ret; /* Mute */ + dvc->mute.max = 1; ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Mute Switch" : "DVC In Mute Switch", - dvc->mute); + &dvc->mute); if (ret < 0) return ret; -- cgit v0.10.2 From 6879db7648b6b995122afa98df31778c7af0855d Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 31 Oct 2014 14:52:16 +0800 Subject: ASoC: rt286: reduce power consumption This patch will optimize the power consumption of rt286. Signed-off-by: Bard Liao Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 4aa555c..97daa80 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -36,11 +36,13 @@ struct rt286_priv { struct regmap *regmap; + struct snd_soc_codec *codec; struct rt286_platform_data pdata; struct i2c_client *i2c; struct snd_soc_jack *jack; struct delayed_work jack_detect_work; int sys_clk; + int clk_id; struct reg_default *index_cache; }; @@ -298,7 +300,6 @@ static int rt286_support_power_controls[] = { static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) { unsigned int val, buf; - int i; *hp = false; *mic = false; @@ -309,67 +310,44 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) if (*hp) { /* power on HV,VERF */ regmap_update_bits(rt286->regmap, - RT286_POWER_CTRL1, 0x1001, 0x0); + RT286_DC_GAIN, 0x200, 0x200); + + snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, + "HV"); + snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, + "VREF"); /* power LDO1 */ - regmap_update_bits(rt286->regmap, - RT286_POWER_CTRL2, 0x4, 0x4); - regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); - regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); + snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, + "LDO1"); + snd_soc_dapm_sync(&rt286->codec->dapm); - msleep(200); - i = 40; - while (((val & 0x0800) == 0) && (i > 0)) { - regmap_read(rt286->regmap, - RT286_CBJ_CTRL2, &val); - i--; - msleep(20); - } + regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); + msleep(50); - if (0x0400 == (val & 0x0700)) { - *mic = false; + regmap_update_bits(rt286->regmap, + RT286_CBJ_CTRL1, 0xfcc0, 0xd400); + msleep(300); + regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); - regmap_write(rt286->regmap, - RT286_SET_MIC1, 0x20); - /* power off HV,VERF */ - regmap_update_bits(rt286->regmap, - RT286_POWER_CTRL1, 0x1001, 0x1001); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL3, 0xc000, 0x0000); - regmap_update_bits(rt286->regmap, - RT286_CBJ_CTRL1, 0x0030, 0x0000); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL2, 0xc000, 0x0000); - } else if ((0x0200 == (val & 0x0700)) || - (0x0100 == (val & 0x0700))) { + if (0x0070 == (val & 0x0070)) { *mic = true; - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL3, 0xc000, 0x8000); - regmap_update_bits(rt286->regmap, - RT286_CBJ_CTRL1, 0x0030, 0x0020); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL2, 0xc000, 0x8000); } else { - *mic = false; + regmap_update_bits(rt286->regmap, + RT286_CBJ_CTRL1, 0xfcc0, 0xe400); + msleep(300); + regmap_read(rt286->regmap, + RT286_CBJ_CTRL2, &val); + if (0x0070 == (val & 0x0070)) + *mic = true; + else + *mic = false; } - - regmap_update_bits(rt286->regmap, - RT286_MISC_CTRL1, - 0x0060, 0x0000); - } else { - regmap_update_bits(rt286->regmap, - RT286_MISC_CTRL1, - 0x0060, 0x0020); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL3, - 0xc000, 0x8000); regmap_update_bits(rt286->regmap, - RT286_CBJ_CTRL1, - 0x0030, 0x0020); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL2, - 0xc000, 0x8000); + RT286_DC_GAIN, 0x200, 0x0); + } else { *mic = false; + regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20); } } else { regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); @@ -378,6 +356,12 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) *mic = buf & 0x80000000; } + snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV"); + snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF"); + if (!*hp) + snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1"); + snd_soc_dapm_sync(&rt286->codec->dapm); + return 0; } @@ -415,6 +399,17 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) } EXPORT_SYMBOL_GPL(rt286_mic_detect); +static int is_mclk_mode(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec); + + if (rt286->clk_id == RT286_SCLK_S_MCLK) + return 1; + else + return 0; +} + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); @@ -568,7 +563,84 @@ static int rt286_adc_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt286_vref_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + RT286_CBJ_CTRL1, 0x0400, 0x0000); + mdelay(50); + break; + default: + return 0; + } + + return 0; +} + +static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30); + break; + default: + return 0; + } + + return 0; +} + +static int rt286_mic1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL3, 0xc000, 0x8000); + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL2, 0xc000, 0x8000); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL3, 0xc000, 0x0000); + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL2, 0xc000, 0x0000); + break; + default: + return 0; + } + + return 0; +} + static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1, + 12, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1, + 0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2, + 2, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1, + 13, 1, rt286_ldo2_event, SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_SUPPLY("MCLK MODE", RT286_PLL_CTRL1, + 5, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM, + 0, 0, rt286_mic1_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + /* Input Lines */ SND_SOC_DAPM_INPUT("DMIC1 Pin"), SND_SOC_DAPM_INPUT("DMIC2 Pin"), @@ -642,6 +714,25 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { }; static const struct snd_soc_dapm_route rt286_dapm_routes[] = { + {"ADC 0", NULL, "MCLK MODE", is_mclk_mode}, + {"ADC 1", NULL, "MCLK MODE", is_mclk_mode}, + {"Front", NULL, "MCLK MODE", is_mclk_mode}, + {"Surround", NULL, "MCLK MODE", is_mclk_mode}, + + {"HP Power", NULL, "LDO1"}, + {"HP Power", NULL, "LDO2"}, + + {"MIC1", NULL, "LDO1"}, + {"MIC1", NULL, "LDO2"}, + {"MIC1", NULL, "HV"}, + {"MIC1", NULL, "VREF"}, + {"MIC1", NULL, "MIC1 Input Buffer"}, + + {"SPO", NULL, "LDO1"}, + {"SPO", NULL, "LDO2"}, + {"SPO", NULL, "HV"}, + {"SPO", NULL, "VREF"}, + {"DMIC1", NULL, "DMIC1 Pin"}, {"DMIC2", NULL, "DMIC2 Pin"}, {"DMIC1", NULL, "DMIC Receiver"}, @@ -880,6 +971,7 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai, } rt286->sys_clk = freq; + rt286->clk_id = clk_id; return 0; } @@ -915,13 +1007,18 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: mdelay(10); + snd_soc_update_bits(codec, + RT286_CBJ_CTRL1, 0x0400, 0x0400); + snd_soc_update_bits(codec, + RT286_DC_GAIN, 0x200, 0x0); + break; case SND_SOC_BIAS_STANDBY: snd_soc_write(codec, RT286_SET_AUDIO_POWER, AC_PWRST_D3); snd_soc_update_bits(codec, - RT286_DC_GAIN, 0x200, 0x0); + RT286_CBJ_CTRL1, 0x0400, 0x0000); break; default: @@ -962,6 +1059,7 @@ static int rt286_probe(struct snd_soc_codec *codec) { struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); + rt286->codec = codec; codec->dapm.bias_level = SND_SOC_BIAS_OFF; if (rt286->i2c->irq) { @@ -1152,7 +1250,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (!rt286->pdata.cbj_en) { regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000); regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816); - regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xf000, 0xb000); } else { @@ -1169,8 +1266,10 @@ static int rt286_i2c_probe(struct i2c_client *i2c, mdelay(10); - /*Power down LDO2*/ - regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x8, 0x0); + regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); + /*Power down LDO, VREF*/ + regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0); + regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001); /*Set depop parameter*/ regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a); -- cgit v0.10.2 From 9ce63dbd5d2671a209a859ee90f7dc6b8f22f28e Mon Sep 17 00:00:00 2001 From: Jianqun Date: Sat, 1 Nov 2014 10:58:18 +0800 Subject: ASoC: rockchip: i2s: add text after tristate for SND_SOC_ROCKCHIP_I2S For SND_SOC_ROCKCHIP_I2S, adding some text after the tristate to make this directly user selectable. Signed-off-by: Jianqun Signed-off-by: Mark Brown diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index 78fc159..b1fc0ca 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -8,4 +8,9 @@ config SND_SOC_ROCKCHIP select the audio interfaces to support below. config SND_SOC_ROCKCHIP_I2S - tristate + tristate "Rockchip I2S Device Driver" + depends on CLKDEV_LOOKUP + help + Say Y or M if you want to add support for I2S driver for + Rockchip I2S device. The device supports upto maximum of + 8 channels each for play and record. -- cgit v0.10.2 From 6c67cde2aa88bb06cd039aa0f61b26df887075d7 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 6 Nov 2014 09:59:59 +0800 Subject: ASoC: rt286: set combo jack by dmi This patch enables combo jack configuration according to dmi. Signed-off-by: Bard Liao Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 97daa80..d4acb64 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -1205,6 +1206,16 @@ static const struct acpi_device_id rt286_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); +static struct dmi_system_id force_combo_jack_table[] __initdata = { + { + .ident = "Intel Wilson Beach", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS") + } + }, + { } +}; + static int rt286_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1240,6 +1251,9 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (pdata) rt286->pdata = *pdata; + if (dmi_check_system(force_combo_jack_table)) + rt286->pdata.cbj_en = true; + regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); for (i = 0; i < RT286_POWER_REG_LEN; i++) -- cgit v0.10.2 From f8c101bc357d509291f6accb6f62b8439158a203 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 6 Nov 2014 10:00:00 +0800 Subject: ASoC: rt286: fix comment style Adds spaces around the /* */. Signed-off-by: Bard Liao Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index d4acb64..2e818aa 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -191,7 +191,7 @@ static int rt286_hw_write(void *context, unsigned int reg, unsigned int value) u8 data[4]; int ret, i; - /*handle index registers*/ + /* handle index registers */ if (reg <= 0xff) { rt286_hw_write(client, RT286_COEF_INDEX, reg); for (i = 0; i < INDEX_CACHE_SIZE; i++) { @@ -234,7 +234,7 @@ static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value) __be32 be_reg; unsigned int index, vid, buf = 0x0; - /*handle index registers*/ + /* handle index registers */ if (reg <= 0xff) { rt286_hw_write(client, RT286_COEF_INDEX, reg); reg = RT286_PROC_COEF; @@ -1281,11 +1281,11 @@ static int rt286_i2c_probe(struct i2c_client *i2c, mdelay(10); regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); - /*Power down LDO, VREF*/ + /* Power down LDO, VREF */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0); regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001); - /*Set depop parameter*/ + /* Set depop parameter */ regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a); regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f); -- cgit v0.10.2 From 1c5d1c988302f324ac396ac13461d59d091be605 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 4 Nov 2014 20:26:53 -0800 Subject: ASoC: rsnd: control DVC_DVUCR under rsnd_dvc_volume_update() rsnd_dvc_volume_update() is main function to control DVC feature like Digital Volume / Mute / Ramp etc. DVC_DVUCR should be controlled under this function. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index deaf0fa..3952237 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -40,6 +40,7 @@ struct rsnd_dvc { static void rsnd_dvc_volume_update(struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u32 dvucr = 0; u32 mute = 0; int i; @@ -47,10 +48,18 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) mute |= (!!dvc->mute.val[i]) << i; } + /* Enable Digital Volume */ + dvucr = 0x100; rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]); rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]); - rsnd_mod_write(mod, DVC_ZCMCR, mute); + /* Enable Mute */ + if (mute) { + dvucr |= 0x1; + rsnd_mod_write(mod, DVC_ZCMCR, mute); + } + + rsnd_mod_write(mod, DVC_DVUCR, dvucr); } static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, @@ -103,9 +112,6 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod)); - /* enable Volume / Mute */ - rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x101); - /* ch0/ch1 Volume */ rsnd_dvc_volume_update(dvc_mod); -- cgit v0.10.2 From 140bab8961eb4047070b46a6dd50ec87496e0cde Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 4 Nov 2014 20:27:18 -0800 Subject: ASoC: rsnd: move DVC_DVUER settings under rsnd_dvc_volume_update() We need to Enable/Disable DVC_DVUER register if we set DVCp_ZCMCR, DVCp_VRCTR, DVCp_VRPDR, DVCp_VRDBR, DVCp_VOL0R, DVCp_VOL1R, DVCp_VOL2R, DVCp_VOL3R, DVCp_VOL4R, DVCp_VOL5R, DVCp_VOL6R, DVCp_VOL7R and, these are controlled under rsnd_dvc_volume_update(). This patch moves DVC_DVUER settings to it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 3952237..ce1512e 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -48,6 +48,9 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) mute |= (!!dvc->mute.val[i]) << i; } + /* Disable DVC Register access */ + rsnd_mod_write(mod, DVC_DVUER, 0); + /* Enable Digital Volume */ dvucr = 0x100; rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]); @@ -60,6 +63,9 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) } rsnd_mod_write(mod, DVC_DVUCR, dvucr); + + /* Enable DVC Register access */ + rsnd_mod_write(mod, DVC_DVUER, 1); } static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, @@ -117,8 +123,6 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); - rsnd_mod_write(dvc_mod, DVC_DVUER, 1); - rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io); return 0; -- cgit v0.10.2 From ec14af91a03f7d68b2a72bec20be2ab583d3f63a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 4 Nov 2014 20:27:46 -0800 Subject: ASoC: rsnd: enable multiple DVC valume settings DVC controls some digital volume features. Some of them requests values for "each channels", but, some of them requests values for "feature". Current dvc.c is supporting Mute/Volume, and these have "each channels" settings. This patch adds rsnd_dvc_cfg_m and care about multiple settings for each channels. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index ce1512e..c729e26 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -17,6 +17,12 @@ struct rsnd_dvc_cfg { unsigned int max; + unsigned int size; + u32 *val; +}; + +struct rsnd_dvc_cfg_m { + struct rsnd_dvc_cfg cfg; u32 val[RSND_DVC_CHANNELS]; }; @@ -24,8 +30,8 @@ struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - struct rsnd_dvc_cfg volume; - struct rsnd_dvc_cfg mute; + struct rsnd_dvc_cfg_m volume; + struct rsnd_dvc_cfg_m mute; }; #define rsnd_mod_to_dvc(_mod) \ @@ -44,9 +50,8 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) u32 mute = 0; int i; - for (i = 0; i < RSND_DVC_CHANNELS; i++) { - mute |= (!!dvc->mute.val[i]) << i; - } + for (i = 0; i < dvc->mute.cfg.size; i++) + mute |= (!!dvc->mute.cfg.val[i]) << i; /* Disable DVC Register access */ rsnd_mod_write(mod, DVC_DVUER, 0); @@ -159,7 +164,7 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, { struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; - uinfo->count = RSND_DVC_CHANNELS; + uinfo->count = cfg->size; uinfo->value.integer.min = 0; uinfo->value.integer.max = cfg->max; @@ -177,7 +182,7 @@ static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i; - for (i = 0; i < RSND_DVC_CHANNELS; i++) + for (i = 0; i < cfg->size; i++) ucontrol->value.integer.value[i] = cfg->val[i]; return 0; @@ -190,7 +195,7 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i, change = 0; - for (i = 0; i < RSND_DVC_CHANNELS; i++) { + for (i = 0; i < cfg->size; i++) { change |= (ucontrol->value.integer.value[i] != cfg->val[i]); cfg->val[i] = ucontrol->value.integer.value[i]; } @@ -230,6 +235,19 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod, return 0; } +static int _rsnd_dvc_pcm_new_m(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + struct rsnd_dvc_cfg_m *private, + u32 max) +{ + private->cfg.max = max; + private->cfg.size = RSND_DVC_CHANNELS; + private->cfg.val = private->val; + return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); +} + static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd) @@ -239,20 +257,18 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, int ret; /* Volume */ - dvc->volume.max = 0x00800000 - 1; - ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, + ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Playback Volume" : "DVC In Capture Volume", - &dvc->volume); + &dvc->volume, 0x00800000 - 1); if (ret < 0) return ret; /* Mute */ - dvc->mute.max = 1; - ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, + ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Mute Switch" : "DVC In Mute Switch", - &dvc->mute); + &dvc->mute, 1); if (ret < 0) return ret; -- cgit v0.10.2 From ab2e479667507329475c8ef93d61f3dbe654c3c2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 4 Nov 2014 20:28:10 -0800 Subject: ASoC: rsnd: enable single DVC valume settings DVC controls some digital volume features. Some of them requests values for "each channels", but, some of them requests values for "feature". And, Volume Ramp has "feature" settings. This patch adds rsnd_dvc_cfg_s and care about single settings. Compiler will report like below at this point, but, it will be removed if Volume Ramp was supported. warning: '_rsnd_dvc_pcm_new_s' defined but not used Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index c729e26..e7cfc71 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -26,6 +26,11 @@ struct rsnd_dvc_cfg_m { u32 val[RSND_DVC_CHANNELS]; }; +struct rsnd_dvc_cfg_s { + struct rsnd_dvc_cfg cfg; + u32 val; +}; + struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; @@ -248,6 +253,19 @@ static int _rsnd_dvc_pcm_new_m(struct rsnd_mod *mod, return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); } +static int _rsnd_dvc_pcm_new_s(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + struct rsnd_dvc_cfg_s *private, + u32 max) +{ + private->cfg.max = max; + private->cfg.size = 1; + private->cfg.val = &private->val; + return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); +} + static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd) -- cgit v0.10.2 From 018342976ce971944dd4d9309f75e86382079a2b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 4 Nov 2014 20:28:50 -0800 Subject: ASoC: rsnd: enable enumerated DVC valume settings DVC controls some digital volume features. Volume Ramp is listed as "XX dB / YY steps", and this enumerated settings are easy for users. This patch adds rsnd_dvc_cfg_e and care about enumerated settings. Compiler will report like below at this point, but, it will be removed if Volume Ramp was supported. warning: '_rsnd_dvc_pcm_new_e' defined but not used Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index e7cfc71..8504f6b 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -19,6 +19,7 @@ struct rsnd_dvc_cfg { unsigned int max; unsigned int size; u32 *val; + const char * const *texts; }; struct rsnd_dvc_cfg_m { @@ -169,14 +170,23 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, { struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; - uinfo->count = cfg->size; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = cfg->max; - - if (cfg->max == 1) - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - else - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + if (cfg->texts) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = cfg->size; + uinfo->value.enumerated.items = cfg->max; + if (uinfo->value.enumerated.item >= cfg->max) + uinfo->value.enumerated.item = cfg->max - 1; + strlcpy(uinfo->value.enumerated.name, + cfg->texts[uinfo->value.enumerated.item], + sizeof(uinfo->value.enumerated.name)); + } else { + uinfo->count = cfg->size; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = cfg->max; + uinfo->type = (cfg->max == 1) ? + SNDRV_CTL_ELEM_TYPE_BOOLEAN : + SNDRV_CTL_ELEM_TYPE_INTEGER; + } return 0; } @@ -188,7 +198,10 @@ static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, int i; for (i = 0; i < cfg->size; i++) - ucontrol->value.integer.value[i] = cfg->val[i]; + if (cfg->texts) + ucontrol->value.enumerated.item[i] = cfg->val[i]; + else + ucontrol->value.integer.value[i] = cfg->val[i]; return 0; } @@ -201,8 +214,13 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, int i, change = 0; for (i = 0; i < cfg->size; i++) { - change |= (ucontrol->value.integer.value[i] != cfg->val[i]); - cfg->val[i] = ucontrol->value.integer.value[i]; + if (cfg->texts) { + change |= (ucontrol->value.enumerated.item[i] != cfg->val[i]); + cfg->val[i] = ucontrol->value.enumerated.item[i]; + } else { + change |= (ucontrol->value.integer.value[i] != cfg->val[i]); + cfg->val[i] = ucontrol->value.integer.value[i]; + } } if (change) @@ -266,6 +284,21 @@ static int _rsnd_dvc_pcm_new_s(struct rsnd_mod *mod, return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); } +static int _rsnd_dvc_pcm_new_e(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + struct rsnd_dvc_cfg_s *private, + const char * const *texts, + u32 max) +{ + private->cfg.max = max; + private->cfg.size = 1; + private->cfg.val = &private->val; + private->cfg.texts = texts; + return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); +} + static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd) -- cgit v0.10.2 From 30cc4faf703955cd5cd07da489bd817ae43e3fec Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 9 Nov 2014 20:00:30 -0800 Subject: ASoC: rsnd: tidyup debug message format and timing Current Renesas R-Car sound driver debug message is using random format (ex "ssi0: xxx" / "SSI0 xxx" / "ssi[0]: xxx") and confusable timing ("xxx probe failed" and "xxx probed" are shown in same time) This patch fixes these Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1922ec5..5205618 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -409,7 +409,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) ({ \ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ struct device *dev = rsnd_priv_to_dev(priv); \ - dev_dbg(dev, "%s [%d] %s\n", \ + dev_dbg(dev, "%s[%d] %s\n", \ rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ (mod)->ops->func(mod, rdai); \ }) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 8504f6b..956b84e 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -85,7 +85,8 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); - dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod)); + dev_dbg(dev, "%s[%d] (Gen2) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return 0; } diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 61dee68..a0fed66 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -78,7 +78,7 @@ u32 rsnd_read(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return 0; - dev_dbg(dev, "r %s(%d) - %4d : %08x\n", + dev_dbg(dev, "r %s[%d] - %4d : %08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); @@ -96,7 +96,7 @@ void rsnd_write(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - dev_dbg(dev, "w %s(%d) - %4d : %08x\n", + dev_dbg(dev, "w %s[%d] - %4d : %08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); @@ -111,7 +111,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - dev_dbg(dev, "b %s(%d) - %4d : %08x/%08x\n", + dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask); regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 9183e01..4679501 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -438,7 +438,8 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod, struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); - dev_dbg(dev, "%s (Gen1) is probed\n", rsnd_mod_name(mod)); + dev_dbg(dev, "%s[%d] (Gen1) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return 0; } @@ -578,9 +579,11 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, rsnd_info_is_playback(priv, src), src->info->dma_id); if (ret < 0) - dev_err(dev, "SRC DMA failed\n"); - - dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod)); + dev_err(dev, "%s[%d] (Gen2) failed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + else + dev_dbg(dev, "%s[%d] (Gen2) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 34e8400..cae08b7 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -159,7 +159,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, ssi->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(j); - dev_dbg(dev, "ssi%d outputs %u Hz\n", + dev_dbg(dev, "%s[%d] outputs %u Hz\n", + rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod), rate); return 0; @@ -206,7 +207,8 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, ssi->usrcnt++; - dev_dbg(dev, "ssi%d hw started\n", rsnd_mod_id(&ssi->mod)); + dev_dbg(dev, "%s[%d] hw started\n", + rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); } static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, @@ -249,7 +251,8 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, clk_disable_unprepare(ssi->clk); } - dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); + dev_dbg(dev, "%s[%d] hw stopped\n", + rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); } /* @@ -385,9 +388,11 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, IRQF_SHARED, dev_name(dev), ssi); if (ret) - dev_err(dev, "SSI request interrupt failed\n"); - - dev_dbg(dev, "%s (PIO) is probed\n", rsnd_mod_name(mod)); + dev_err(dev, "%s[%d] (PIO) request interrupt failed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + else + dev_dbg(dev, "%s[%d] (PIO) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } @@ -448,9 +453,11 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, dma_id); if (ret < 0) - dev_err(dev, "SSI DMA failed\n"); - - dev_dbg(dev, "%s (DMA) is probed\n", rsnd_mod_name(mod)); + dev_err(dev, "%s[%d] (DMA) is failed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + else + dev_dbg(dev, "%s[%d] (DMA) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } -- cgit v0.10.2 From d3a768233243b5892a9c74b85896b9e8c017b259 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 9 Nov 2014 20:00:58 -0800 Subject: ASoC: rsnd: fallback to PIO mode if DMA mode was failed Current Renesas R-Car sound driver probe will be failed if it try to use DMA mode and it couldn't use for some reasons. But PIO mode works even though in such case. This patch try to fallback to PIO mode if DMA mode probing was failed. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 5205618..110b99d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -349,7 +349,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, dma_name); if (!dma->chan) { dev_err(dev, "can't get dma channel\n"); - return -EIO; + goto rsnd_dma_channel_err; } ret = dmaengine_slave_config(dma->chan, &cfg); @@ -363,8 +363,15 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, rsnd_dma_init_err: rsnd_dma_quit(priv, dma); +rsnd_dma_channel_err: - return ret; + /* + * DMA failed. try to PIO mode + * see + * rsnd_ssi_dma_remove() + * rsnd_rdai_continuance_probe() + */ + return -EAGAIN; } void rsnd_dma_quit(struct rsnd_priv *priv, @@ -456,6 +463,13 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, return 0; } +static void rsnd_dai_disconnect(struct rsnd_mod *mod, + struct rsnd_dai_stream *io) +{ + mod->io = NULL; + io->mod[mod->type] = NULL; +} + int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) { int id = rdai - priv->rdai; @@ -686,6 +700,20 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { ret; \ }) +#define rsnd_path_break(priv, io, type) \ +{ \ + struct rsnd_mod *mod; \ + int id = -1; \ + \ + if (rsnd_is_enable_path(io, type)) { \ + id = rsnd_info_id(priv, io, type); \ + if (id >= 0) { \ + mod = rsnd_##type##_mod_get(priv, id); \ + rsnd_dai_disconnect(mod, io); \ + } \ + } \ +} + static int rsnd_path_init(struct rsnd_priv *priv, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) @@ -977,6 +1005,44 @@ static const struct snd_soc_component_driver rsnd_soc_component = { .name = "rsnd", }; +static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, + struct rsnd_dai *rdai, + int is_play) +{ + struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture; + int ret; + + ret = rsnd_dai_call(probe, io, rdai); + if (ret == -EAGAIN) { + /* + * Fallback to PIO mode + */ + + /* + * call "remove" for SSI/SRC/DVC + * SSI will be switch to PIO mode if it was DMA mode + * see + * rsnd_dma_init() + * rsnd_ssi_dma_remove() + */ + rsnd_dai_call(remove, io, rdai); + + /* + * remove SRC/DVC from DAI, + */ + rsnd_path_break(priv, io, src); + rsnd_path_break(priv, io, dvc); + + /* + * retry to "probe". + * DAI has SSI which is PIO mode only now. + */ + ret = rsnd_dai_call(probe, io, rdai); + } + + return ret; +} + /* * rsnd probe */ @@ -1038,11 +1104,11 @@ static int rsnd_probe(struct platform_device *pdev) } for_each_rsnd_dai(rdai, priv, i) { - ret = rsnd_dai_call(probe, &rdai->playback, rdai); + ret = rsnd_rdai_continuance_probe(priv, rdai, 1); if (ret) goto exit_snd_probe; - ret = rsnd_dai_call(probe, &rdai->capture, rdai); + ret = rsnd_rdai_continuance_probe(priv, rdai, 0); if (ret) goto exit_snd_probe; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index cae08b7..346d3dc 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -465,8 +465,23 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct rsnd_dai *rdai) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); + rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); + /* + * fallback to PIO + * + * SSI .probe might be called again. + * see + * rsnd_rdai_continuance_probe() + */ + mod->ops = &rsnd_ssi_pio_ops; + + dev_info(dev, "%s[%d] fallback to PIO mode\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + return 0; } -- cgit v0.10.2 From 3539cacff2031f6d47881c5f3a4932b0ad5ec224 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 9 Nov 2014 19:52:06 -0800 Subject: ASoC: rsnd: Add Volume Ramp support This patch adds Volume Ramp to Renesas sound driver. amixer set "DVC Out" 100% amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" amixer set "DVC Out Ramp" on aplay xxx.wav & amixer set "DVC Out" 80% // Volume Down amixer set "DVC Out" 100% // Volume Up Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 956b84e..e2c8473 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -38,6 +38,9 @@ struct rsnd_dvc { struct clk *clk; struct rsnd_dvc_cfg_m volume; struct rsnd_dvc_cfg_m mute; + struct rsnd_dvc_cfg_s ren; /* Ramp Enable */ + struct rsnd_dvc_cfg_s rup; /* Ramp Rate Up */ + struct rsnd_dvc_cfg_s rdown; /* Ramp Rate Down */ }; #define rsnd_mod_to_dvc(_mod) \ @@ -49,9 +52,37 @@ struct rsnd_dvc { ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ i++) +static const char const *dvc_ramp_rate[] = { + "128 dB/1 step", /* 00000 */ + "64 dB/1 step", /* 00001 */ + "32 dB/1 step", /* 00010 */ + "16 dB/1 step", /* 00011 */ + "8 dB/1 step", /* 00100 */ + "4 dB/1 step", /* 00101 */ + "2 dB/1 step", /* 00110 */ + "1 dB/1 step", /* 00111 */ + "0.5 dB/1 step", /* 01000 */ + "0.25 dB/1 step", /* 01001 */ + "0.125 dB/1 step", /* 01010 */ + "0.125 dB/2 steps", /* 01011 */ + "0.125 dB/4 steps", /* 01100 */ + "0.125 dB/8 steps", /* 01101 */ + "0.125 dB/16 steps", /* 01110 */ + "0.125 dB/32 steps", /* 01111 */ + "0.125 dB/64 steps", /* 10000 */ + "0.125 dB/128 steps", /* 10001 */ + "0.125 dB/256 steps", /* 10010 */ + "0.125 dB/512 steps", /* 10011 */ + "0.125 dB/1024 steps", /* 10100 */ + "0.125 dB/2048 steps", /* 10101 */ + "0.125 dB/4096 steps", /* 10110 */ + "0.125 dB/8192 steps", /* 10111 */ +}; + static void rsnd_dvc_volume_update(struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u32 val[RSND_DVC_CHANNELS]; u32 dvucr = 0; u32 mute = 0; int i; @@ -62,10 +93,35 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) /* Disable DVC Register access */ rsnd_mod_write(mod, DVC_DVUER, 0); + /* Enable Ramp */ + if (dvc->ren.val) { + dvucr |= 0x10; + + /* Digital Volume Max */ + for (i = 0; i < RSND_DVC_CHANNELS; i++) + val[i] = dvc->volume.cfg.max; + + rsnd_mod_write(mod, DVC_VRCTR, 0xff); + rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 | + dvc->rdown.val); + /* + * FIXME !! + * use scale-downed Digital Volume + * as Volume Ramp + * 7F FFFF -> 3FF + */ + rsnd_mod_write(mod, DVC_VRDBR, + 0x3ff - (dvc->volume.val[0] >> 13)); + + } else { + for (i = 0; i < RSND_DVC_CHANNELS; i++) + val[i] = dvc->volume.val[i]; + } + /* Enable Digital Volume */ - dvucr = 0x100; - rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]); - rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]); + dvucr |= 0x100; + rsnd_mod_write(mod, DVC_VOL0R, val[0]); + rsnd_mod_write(mod, DVC_VOL1R, val[1]); /* Enable Mute */ if (mute) { @@ -324,6 +380,31 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, if (ret < 0) return ret; + /* Ramp */ + ret = _rsnd_dvc_pcm_new_s(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Ramp Switch" : "DVC In Ramp Switch", + &dvc->ren, 1); + if (ret < 0) + return ret; + + ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", + &dvc->rup, + dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); + if (ret < 0) + return ret; + + ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", + &dvc->rdown, + dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); + + if (ret < 0) + return ret; + return 0; } diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index a0fed66..87a6f2d 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -324,6 +324,9 @@ static int rsnd_gen2_probe(struct platform_device *pdev, RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100), RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100), RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100), + RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100), + RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100), + RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index d119adf..ed44ca8 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -91,6 +91,9 @@ enum rsnd_reg { RSND_REG_SHARE20, RSND_REG_SHARE21, RSND_REG_SHARE22, + RSND_REG_SHARE23, + RSND_REG_SHARE24, + RSND_REG_SHARE25, RSND_REG_MAX, }; @@ -129,6 +132,9 @@ enum rsnd_reg { #define RSND_REG_CMD_CTRL RSND_REG_SHARE20 #define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21 #define RSND_REG_BUSIF_DALIGN RSND_REG_SHARE22 +#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23 +#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24 +#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25 struct rsnd_of_data; struct rsnd_priv; -- cgit v0.10.2 From 56ba98acc398883324c0e70dc8aee1dc53eb2331 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 10 Nov 2014 20:00:42 +0100 Subject: ASoC: rsnd: Document SoC-specific bindings The documentation only mentioned the generic fallback compatible property. Add the missing SoC-specific compatible properties, which are already in use. Also drop a bogus 0x unit-address prefix while we're at it. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index aa697ab..2dd690b 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -1,8 +1,12 @@ Renesas R-Car sound Required properties: -- compatible : "renesas,rcar_sound-gen1" if generation1 +- compatible : "renesas,rcar_sound-", fallbacks + "renesas,rcar_sound-gen1" if generation1, and "renesas,rcar_sound-gen2" if generation2 + Examples with soctypes are: + - "renesas,rcar_sound-r8a7790" (R-Car H2) + - "renesas,rcar_sound-r8a7791" (R-Car M2-W) - reg : Should contain the register physical address. required register is SRU/ADG/SSI if generation1 @@ -35,9 +39,9 @@ DAI subnode properties: Example: -rcar_sound: rcar_sound@0xffd90000 { +rcar_sound: rcar_sound@ec500000 { #sound-dai-cells = <1>; - compatible = "renesas,rcar_sound-gen2"; + compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2"; reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ -- cgit v0.10.2 From 9e6280cd44c1cceaaac921567ee8c5731b7cc72b Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Thu, 13 Nov 2014 17:44:21 +0530 Subject: ASoC: rt5631: Add device tree binding documentation Document the device tree binding for the ALC5631 codec and update vendor specific prefix for the Realtek. Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/sound/rt5631.txt b/Documentation/devicetree/bindings/sound/rt5631.txt new file mode 100644 index 0000000..92b986c --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5631.txt @@ -0,0 +1,48 @@ +ALC5631/RT5631 audio CODEC + +This device supports I2C only. + +Required properties: + + - compatible : "realtek,alc5631" or "realtek,rt5631" + + - reg : the I2C address of the device. + +Pins on the device (for linking into audio routes): + + * SPK_OUT_R_P + * SPK_OUT_R_N + * SPK_OUT_L_P + * SPK_OUT_L_N + * HP_OUT_L + * HP_OUT_R + * AUX_OUT2_LP + * AUX_OUT2_RN + * AUX_OUT1_LP + * AUX_OUT1_RN + * AUX_IN_L_JD + * AUX_IN_R_JD + * MONO_IN_P + * MONO_IN_N + * MIC1_P + * MIC1_N + * MIC2_P + * MIC2_N + * MONO_OUT_P + * MONO_OUT_N + * MICBIAS1 + * MICBIAS2 + +Example: + +alc5631: alc5631@1a { + compatible = "realtek,alc5631"; + reg = <0x1a>; +}; + +or + +rt5631: rt5631@1a { + compatible = "realtek,rt5631"; + reg = <0x1a>; +}; -- cgit v0.10.2 From 86707f7fece1d3a34aeb1e9c7f2178fd5ff4e788 Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Thu, 13 Nov 2014 17:44:23 +0530 Subject: ASoC: rt5631: Adding the description of the codec Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d173..7e43e97 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -487,7 +487,8 @@ config SND_SOC_RT286 depends on I2C config SND_SOC_RT5631 - tristate + tristate "Realtek ALC5631/RT5631 CODEC" + depends on I2C config SND_SOC_RT5640 tristate -- cgit v0.10.2 From 189c88ced169d5197c806828e275c6f063b1d499 Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Thu, 13 Nov 2014 17:44:24 +0530 Subject: ASoC: rt5631: Adding Device Tree compatibility to Realtek's ALC5631/RT5631 codec driver Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 1ba27db..3b7d5e4 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1686,10 +1686,18 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { static const struct i2c_device_id rt5631_i2c_id[] = { { "rt5631", 0 }, + { "alc5631", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); +static struct of_device_id rt5631_i2c_dt_ids[] = { + { .compatible = "realtek,rt5631"}, + { .compatible = "realtek,alc5631"}, + { } +}; +MODULE_DEVICE_TABLE(of, rt5631_i2c_dt_ids); + static const struct regmap_config rt5631_regmap_config = { .reg_bits = 8, .val_bits = 16, @@ -1734,6 +1742,7 @@ static struct i2c_driver rt5631_i2c_driver = { .driver = { .name = "rt5631", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rt5631_i2c_dt_ids), }, .probe = rt5631_i2c_probe, .remove = rt5631_i2c_remove, -- cgit v0.10.2 From 187024b36c635bd454c1b1587b58c9439d3a46ad Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Mon, 17 Nov 2014 19:26:29 +0530 Subject: ASoC: rt5631: Fixing compilation warning when DT is disabled Fixes the following compilation warning: Warning: 'rt5631_i2c_dt_ids' defined but not used - when DT is not used. Signed-off-by: Claude Youn Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 3b7d5e4..9425545 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1691,12 +1691,14 @@ static const struct i2c_device_id rt5631_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); +#ifdef CONFIG_OF static struct of_device_id rt5631_i2c_dt_ids[] = { { .compatible = "realtek,rt5631"}, { .compatible = "realtek,alc5631"}, { } }; MODULE_DEVICE_TABLE(of, rt5631_i2c_dt_ids); +#endif static const struct regmap_config rt5631_regmap_config = { .reg_bits = 8, -- cgit v0.10.2 From a5a267cf9ca9937b0ef946b502657ae7638282f6 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 18 Nov 2014 17:42:54 +0530 Subject: ASoC: rt286: build warning of section mismatch while building we were getting the following build warning: Section mismatch in reference from the function rt286_i2c_probe() to the variable .init.data:force_combo_jack_table The function rt286_i2c_probe() references the variable __initdata force_combo_jack_table. This is often because rt286_i2c_probe lacks a __initdata annotation or the annotation of force_combo_jack_table is wrong. we were getting the warning as force_combo_jack_table was marked with __initdata Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 2e818aa..2cd4fe4 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1206,7 +1206,7 @@ static const struct acpi_device_id rt286_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); -static struct dmi_system_id force_combo_jack_table[] __initdata = { +static struct dmi_system_id force_combo_jack_table[] = { { .ident = "Intel Wilson Beach", .matches = { -- cgit v0.10.2 From e2dce944cc2bf22d0295330cbdcbd2ad7bd47cb4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:47:52 +0100 Subject: ASoC: rt5631: Cleanup bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 9425545..6d7b7ca 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1612,29 +1612,6 @@ static int rt5631_probe(struct snd_soc_codec *codec) return 0; } -static int rt5631_remove(struct snd_soc_codec *codec) -{ - rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -#ifdef CONFIG_PM -static int rt5631_suspend(struct snd_soc_codec *codec) -{ - rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int rt5631_resume(struct snd_soc_codec *codec) -{ - rt5631_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define rt5631_suspend NULL -#define rt5631_resume NULL -#endif - #define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000 #define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S20_3LE | \ @@ -1672,10 +1649,8 @@ static struct snd_soc_dai_driver rt5631_dai[] = { static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { .probe = rt5631_probe, - .remove = rt5631_remove, - .suspend = rt5631_suspend, - .resume = rt5631_resume, .set_bias_level = rt5631_set_bias_level, + .suspend_bias_off = true, .controls = rt5631_snd_controls, .num_controls = ARRAY_SIZE(rt5631_snd_controls), .dapm_widgets = rt5631_dapm_widgets, -- cgit v0.10.2 From 8d213de7ffff614e3aa751a31a8980e1be3036e1 Mon Sep 17 00:00:00 2001 From: Andreas Ruprecht Date: Fri, 21 Nov 2014 20:50:46 +0100 Subject: ASoC: rockchip: i2s: Fix Kconfig for I2S device driver Currently, CONFIG_SND_SOC_ROCKCHIP_I2S could also be selected without having CONFIG_SND_SOC_ROCKCHIP enabled. As this makes no sense, a Kconfig dependency is added to CONFIG_SND_SOC_ROCKCHIP_I2S. This will make the item visible only if CONFIG_SND_SOC_ROCKCHIP is enabled. Additionally, as the code connected to CONFIG_SND_SOC_ROCKCHIP_I2S depends on CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM, the dependency is moved to reflect this more clearly. Signed-off-by: Andreas Ruprecht Reported-by: Jim Davis Signed-off-by: Mark Brown diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index b1fc0ca..e181826 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -1,7 +1,6 @@ config SND_SOC_ROCKCHIP tristate "ASoC support for Rockchip" depends on COMPILE_TEST || ARCH_ROCKCHIP - select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the Rockchip SoCs' Audio interfaces. You will also need to @@ -9,7 +8,8 @@ config SND_SOC_ROCKCHIP config SND_SOC_ROCKCHIP_I2S tristate "Rockchip I2S Device Driver" - depends on CLKDEV_LOOKUP + depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP + select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for I2S driver for Rockchip I2S device. The device supports upto maximum of -- cgit v0.10.2 From 97463e193654574e1533f71359d91d9d2fdb3571 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:02:43 +0000 Subject: ASoC: rsnd: add .fallback callback Current R-Car sound has PIO fallback support if it couldn't use DMA. This fallback is done in .remove callback, but, it should have .fallback callback. Otherwise, normal .remove callback will have strange behavior. This patch adds .fallback callback. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 110b99d..0785f84 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -368,7 +368,7 @@ rsnd_dma_channel_err: /* * DMA failed. try to PIO mode * see - * rsnd_ssi_dma_remove() + * rsnd_ssi_fallback() * rsnd_rdai_continuance_probe() */ return -EAGAIN; @@ -1023,7 +1023,7 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, * SSI will be switch to PIO mode if it was DMA mode * see * rsnd_dma_init() - * rsnd_ssi_dma_remove() + * rsnd_ssi_fallback() */ rsnd_dai_call(remove, io, rdai); @@ -1034,6 +1034,11 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, rsnd_path_break(priv, io, dvc); /* + * fallback + */ + rsnd_dai_call(fallback, io, rdai); + + /* * retry to "probe". * DAI has SSI which is PIO mode only now. */ diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index ed44ca8..83e1066 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -206,6 +206,8 @@ struct rsnd_mod_ops { int (*pcm_new)(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd); + int (*fallback)(struct rsnd_mod *mod, + struct rsnd_dai *rdai); }; struct rsnd_dai_stream; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 346d3dc..e03e70b 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -465,11 +465,17 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct rsnd_dai *rdai) { + rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); + + return 0; +} + +static int rsnd_ssi_fallback(struct rsnd_mod *mod, + struct rsnd_dai *rdai) +{ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); - rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); - /* * fallback to PIO * @@ -541,6 +547,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = { .quit = rsnd_ssi_quit, .start = rsnd_ssi_dma_start, .stop = rsnd_ssi_dma_stop, + .fallback = rsnd_ssi_fallback, }; /* -- cgit v0.10.2 From 417f96420a5823485b90ad7ee9fddb67996bbd7f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:02:55 +0000 Subject: ASoC: rsnd: add callback status check method R-Car sound can use SSI/SRC/DVC modules, and these are controlled as rsnd_mod in rsnd driver. These rsnd_mod has each own function as callback. Basically these callback function has pair like probe/remove, start/stop, etc. And, these functions are called by order to each stage like below. 1. src->probe 2. ssi->probe 3. dvc->probe 4. src->start 5. ssi->start 6. dvc->start 7. src->stop 8. ssi->stop 9. dvc->stop 10. src->remove 11. ssi->remove 12. dvc->remove But, current rsnd driver doesn't care about its status which indicates which function is called. For example, if 5) returns error, 6) is not called. In such case, 9) should not be called. This patch care about each modules status. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 0785f84..fce61a0 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -416,9 +416,16 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) ({ \ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ struct device *dev = rsnd_priv_to_dev(priv); \ - dev_dbg(dev, "%s[%d] %s\n", \ - rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ - (mod)->ops->func(mod, rdai); \ + u32 mask = 1 << __rsnd_mod_shift_##func; \ + u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \ + int ret = 0; \ + if ((mod->status & mask) == call) { \ + dev_dbg(dev, "%s[%d] %s\n", \ + rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ + ret = (mod)->ops->func(mod, rdai); \ + mod->status = (mod->status & ~mask) | (~call & mask); \ + } \ + ret; \ }) #define rsnd_mod_call(mod, func, rdai...) \ diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 83e1066..c74c239 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -218,7 +218,35 @@ struct rsnd_mod { struct rsnd_mod_ops *ops; struct rsnd_dma dma; struct rsnd_dai_stream *io; + u32 status; }; +/* + * status + * + * bit + * 0 0: probe 1: remove + * 1 0: init 1: quit + * 2 0: start 1: stop + * 3 0: pcm_new + * 4 0: fallback + */ +#define __rsnd_mod_shift_probe 0 +#define __rsnd_mod_shift_remove 0 +#define __rsnd_mod_shift_init 1 +#define __rsnd_mod_shift_quit 1 +#define __rsnd_mod_shift_start 2 +#define __rsnd_mod_shift_stop 2 +#define __rsnd_mod_shift_pcm_new 3 +#define __rsnd_mod_shift_fallback 4 + +#define __rsnd_mod_call_probe 0 +#define __rsnd_mod_call_remove 1 +#define __rsnd_mod_call_init 0 +#define __rsnd_mod_call_quit 1 +#define __rsnd_mod_call_start 0 +#define __rsnd_mod_call_stop 1 +#define __rsnd_mod_call_pcm_new 0 +#define __rsnd_mod_call_fallback 0 #define rsnd_mod_to_priv(mod) ((mod)->priv) #define rsnd_mod_to_dma(mod) (&(mod)->dma) -- cgit v0.10.2 From 660cdce2fbdcbe48eb143cc394fdb24316232dba Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:03:39 +0000 Subject: ASoC: rsnd: rsnd_src_ssiu_stop() stops SSIU compulsorily rsnd_src_ssiu_stop() is used to stop SSIU, but it shouldn't depend on whether it is using SSIU. This patch stops SSIU compulsorily. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index c74c239..1344c3a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -431,8 +431,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, struct rsnd_dai *rdai, int use_busif); int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, - struct rsnd_dai *rdai, - int use_busif); + struct rsnd_dai *rdai); int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, struct rsnd_dai *rdai); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 4679501..384af90 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -175,14 +175,12 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, } int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, - struct rsnd_dai *rdai, - int use_busif) + struct rsnd_dai *rdai) { /* * DMA settings for SSIU */ - if (use_busif) - rsnd_mod_write(ssi_mod, SSI_CTRL, 0); + rsnd_mod_write(ssi_mod, SSI_CTRL, 0); return 0; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index e03e70b..a200452 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -424,7 +424,7 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, rsnd_ssi_hw_stop(ssi, rdai); - rsnd_src_ssiu_stop(mod, rdai, 0); + rsnd_src_ssiu_stop(mod, rdai); return 0; } @@ -528,7 +528,7 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, rsnd_dma_stop(dma); - rsnd_src_ssiu_stop(mod, rdai, 1); + rsnd_src_ssiu_stop(mod, rdai); return 0; } -- cgit v0.10.2 From 05795411aeda8a86865b595e09f22273d85fce83 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:05:01 +0000 Subject: ASoC: rsnd: tidyup PIO/DMA mode settings method Current ssi.c has .cr_etc which is used for SSICR's etc settings. but, it is used as PIO/DMA switching purpose now. This patch tidyup this method. This is prepare for under/over run issue handling Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 1344c3a..12e8945 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -445,6 +445,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, struct rsnd_priv *priv); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); +int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); /* * R-Car DVC diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index a200452..8928913 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -68,7 +68,6 @@ struct rsnd_ssi { struct rsnd_dai *rdai; u32 cr_own; u32 cr_clk; - u32 cr_etc; int err; unsigned int usrcnt; unsigned int rate; @@ -185,6 +184,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, { struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); struct device *dev = rsnd_priv_to_dev(priv); + u32 cr_mode; u32 cr; if (0 == ssi->usrcnt) { @@ -198,9 +198,14 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, } } + cr_mode = rsnd_ssi_is_dma_mode(&ssi->mod) ? + DMEN : /* DMA : use DMA */ + UIEN | OIEN | DIEN; /* PIO : enable interrupt */ + + cr = ssi->cr_own | ssi->cr_clk | - ssi->cr_etc | + cr_mode | EN; rsnd_mod_write(&ssi->mod, SSICR, cr); @@ -403,9 +408,6 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - /* enable PIO IRQ */ - ssi->cr_etc = UIEN | OIEN | DIEN; - rsnd_src_ssiu_start(mod, rdai, 0); rsnd_src_enable_ssi_irq(mod, rdai); @@ -420,8 +422,6 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - ssi->cr_etc = 0; - rsnd_ssi_hw_stop(ssi, rdai); rsnd_src_ssiu_stop(mod, rdai); @@ -498,9 +498,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - /* enable DMA transfer */ - ssi->cr_etc = DMEN; - rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); rsnd_dma_start(dma); @@ -520,8 +517,6 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); - ssi->cr_etc = 0; - rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); rsnd_ssi_hw_stop(ssi, rdai); @@ -550,6 +545,12 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = { .fallback = rsnd_ssi_fallback, }; +int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod) +{ + return mod->ops == &rsnd_ssi_dma_ops; +} + + /* * Non SSI */ -- cgit v0.10.2 From c17dba8b8e198758a4f61fe89e16106b82af18a9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:05:09 +0000 Subject: ASoC: rsnd: tidyup SSI interrupt enable/disable method Current SSI doesn't care interrupt "disable" method. And, it is used when PIO mode only at this point. SSI interrupt will be used for sound R/L issue workaround when DMA mode too. This patch tidyup SSI interrupt enable/disable method. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 12e8945..48999b1 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -432,8 +432,10 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, int use_busif); int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, struct rsnd_dai *rdai); -int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, +int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, struct rsnd_dai *rdai); +int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod, + struct rsnd_dai *rdai); #define rsnd_src_nr(priv) ((priv)->src_nr) diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 384af90..c301195 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -185,18 +185,37 @@ int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, return 0; } -int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, +int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, struct rsnd_dai *rdai) { struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); - /* enable PIO interrupt if Gen2 */ - if (rsnd_is_gen2(priv)) + if (rsnd_is_gen1(priv)) + return 0; + + /* enable SSI interrupt if Gen2 */ + if (rsnd_ssi_is_dma_mode(ssi_mod)) + rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0e000000); + else rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000); return 0; } +int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod, + struct rsnd_dai *rdai) +{ + struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); + + if (rsnd_is_gen1(priv)) + return 0; + + /* disable SSI interrupt if Gen2 */ + rsnd_mod_write(ssi_mod, INT_ENABLE, 0x00000000); + + return 0; +} + unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, struct rsnd_dai_stream *io, struct snd_pcm_runtime *runtime) diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 8928913..42d7c7e 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -410,10 +410,10 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, rsnd_src_ssiu_start(mod, rdai, 0); - rsnd_src_enable_ssi_irq(mod, rdai); - rsnd_ssi_hw_start(ssi, rdai, io); + rsnd_src_ssi_irq_enable(mod, rdai); + return 0; } @@ -422,6 +422,8 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + rsnd_src_ssi_irq_disable(mod, rdai); + rsnd_ssi_hw_stop(ssi, rdai); rsnd_src_ssiu_stop(mod, rdai); -- cgit v0.10.2 From d1b64056d479a115e02c88ab63bc2406a0c46468 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:05:34 +0000 Subject: ASoC: rsnd: care SSIWSR register in rsnd_ssi_hw_start() Current SSI is careing SSIWSR which controls WS continue mode when DMA mode, but, it should be cared when PIO mode too. This patch fixup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 42d7c7e..d67bca9 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -210,6 +210,10 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, rsnd_mod_write(&ssi->mod, SSICR, cr); + /* enable WS continue */ + if (rsnd_dai_is_clk_master(rdai)) + rsnd_mod_write(&ssi->mod, SSIWSR, CONT); + ssi->usrcnt++; dev_dbg(dev, "%s[%d] hw started\n", @@ -506,10 +510,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, rsnd_ssi_hw_start(ssi, ssi->rdai, io); - /* enable WS continue */ - if (rsnd_dai_is_clk_master(rdai)) - rsnd_mod_write(&ssi->mod, SSIWSR, CONT); - return 0; } -- cgit v0.10.2 From 3ba84f45231c19af2ca281273e4fca8df65de341 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:05:44 +0000 Subject: ASoC: rsnd: clear status register when HW start Let's clear SSI status when HW start Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index d67bca9..3c0d31d 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -214,6 +214,9 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, if (rsnd_dai_is_clk_master(rdai)) rsnd_mod_write(&ssi->mod, SSIWSR, CONT); + /* clear error status */ + rsnd_mod_write(&ssi->mod, SSISR, 0); + ssi->usrcnt++; dev_dbg(dev, "%s[%d] hw started\n", -- cgit v0.10.2 From 7b466fc6130a4183b505ebbd8220b55335f69d88 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:05:54 +0000 Subject: ASoC: rsnd: synchronize SSI start/stop sequence between PIO/DMA mode Current SSI start/stop sequence is different between PIO/DMA mode, but, almost all are same. this patch synchronize it. It will be shared in the future. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 3c0d31d..292e98b 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -95,6 +95,9 @@ static int rsnd_ssi_use_busif(struct rsnd_mod *mod) struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); int use_busif = 0; + if (!rsnd_ssi_is_dma_mode(mod)) + return 0; + if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF)) use_busif = 1; if (rsnd_io_to_mod_src(io)) @@ -415,7 +418,7 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - rsnd_src_ssiu_start(mod, rdai, 0); + rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); rsnd_ssi_hw_start(ssi, rdai, io); @@ -431,6 +434,8 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, rsnd_src_ssi_irq_disable(mod, rdai); + rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); + rsnd_ssi_hw_stop(ssi, rdai); rsnd_src_ssiu_stop(mod, rdai); @@ -509,10 +514,10 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); - rsnd_dma_start(dma); - rsnd_ssi_hw_start(ssi, ssi->rdai, io); + rsnd_dma_start(dma); + return 0; } @@ -522,12 +527,12 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); + rsnd_dma_stop(dma); + rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); rsnd_ssi_hw_stop(ssi, rdai); - rsnd_dma_stop(dma); - rsnd_src_ssiu_stop(mod, rdai); return 0; -- cgit v0.10.2 From 4d24d44e4d368314f23159ad833fc6bd15868c1a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:06:03 +0000 Subject: ASoC: rsnd: show master clock rate when ADG probe master clock rate is useful information for debug. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index fc41a0e..14d1a71 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -430,7 +430,7 @@ int rsnd_adg_probe(struct platform_device *pdev, adg->clk[CLKI] = devm_clk_get(dev, "clk_i"); for_each_rsnd_clk(clk, adg, i) - dev_dbg(dev, "clk %d : %p\n", i, clk); + dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk)); rsnd_adg_ssi_clk_init(priv, adg); -- cgit v0.10.2 From 170a2497a25688f4c6bbf011208fc5fe144ef59c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:06:14 +0000 Subject: ASoC: rsnd: move snd_kcontrol_new fucntions to core.c Current DVC is using snd_kcontrol_new functions, but, SRC will need same method. Move common functions to core.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index fce61a0..77af008 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -970,6 +970,150 @@ static struct snd_pcm_ops rsnd_pcm_ops = { }; /* + * snd_kcontrol + */ +#define kcontrol_to_cfg(kctrl) ((struct rsnd_kctrl_cfg *)kctrl->private_value) +static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, + struct snd_ctl_elem_info *uinfo) +{ + struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + + if (cfg->texts) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = cfg->size; + uinfo->value.enumerated.items = cfg->max; + if (uinfo->value.enumerated.item >= cfg->max) + uinfo->value.enumerated.item = cfg->max - 1; + strlcpy(uinfo->value.enumerated.name, + cfg->texts[uinfo->value.enumerated.item], + sizeof(uinfo->value.enumerated.name)); + } else { + uinfo->count = cfg->size; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = cfg->max; + uinfo->type = (cfg->max == 1) ? + SNDRV_CTL_ELEM_TYPE_BOOLEAN : + SNDRV_CTL_ELEM_TYPE_INTEGER; + } + + return 0; +} + +static int rsnd_kctrl_get(struct snd_kcontrol *kctrl, + struct snd_ctl_elem_value *uc) +{ + struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + int i; + + for (i = 0; i < cfg->size; i++) + if (cfg->texts) + uc->value.enumerated.item[i] = cfg->val[i]; + else + uc->value.integer.value[i] = cfg->val[i]; + + return 0; +} + +static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, + struct snd_ctl_elem_value *uc) +{ + struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); + struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + int i, change = 0; + + for (i = 0; i < cfg->size; i++) { + if (cfg->texts) { + change |= (uc->value.enumerated.item[i] != cfg->val[i]); + cfg->val[i] = uc->value.enumerated.item[i]; + } else { + change |= (uc->value.integer.value[i] != cfg->val[i]); + cfg->val[i] = uc->value.integer.value[i]; + } + } + + if (change) + cfg->update(mod); + + return change; +} + +static int __rsnd_kctrl_new(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + struct rsnd_kctrl_cfg *cfg, + void (*update)(struct rsnd_mod *mod)) +{ + struct snd_card *card = rtd->card->snd_card; + struct snd_kcontrol *kctrl; + struct snd_kcontrol_new knew = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = name, + .info = rsnd_kctrl_info, + .get = rsnd_kctrl_get, + .put = rsnd_kctrl_put, + .private_value = (unsigned long)cfg, + }; + int ret; + + kctrl = snd_ctl_new1(&knew, mod); + if (!kctrl) + return -ENOMEM; + + ret = snd_ctl_add(card, kctrl); + if (ret < 0) + return ret; + + cfg->update = update; + + return 0; +} + +int rsnd_kctrl_new_m(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + void (*update)(struct rsnd_mod *mod), + struct rsnd_kctrl_cfg_m *_cfg, + u32 max) +{ + _cfg->cfg.max = max; + _cfg->cfg.size = RSND_DVC_CHANNELS; + _cfg->cfg.val = _cfg->val; + return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); +} + +int rsnd_kctrl_new_s(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + void (*update)(struct rsnd_mod *mod), + struct rsnd_kctrl_cfg_s *_cfg, + u32 max) +{ + _cfg->cfg.max = max; + _cfg->cfg.size = 1; + _cfg->cfg.val = &_cfg->val; + return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); +} + +int rsnd_kctrl_new_e(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + struct rsnd_kctrl_cfg_s *_cfg, + void (*update)(struct rsnd_mod *mod), + const char * const *texts, + u32 max) +{ + _cfg->cfg.max = max; + _cfg->cfg.size = 1; + _cfg->cfg.val = &_cfg->val; + _cfg->cfg.texts = texts; + return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); +} + +/* * snd_soc_platform */ diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index e2c8473..5380a48 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -11,36 +11,18 @@ #include "rsnd.h" #define RSND_DVC_NAME_SIZE 16 -#define RSND_DVC_CHANNELS 2 #define DVC_NAME "dvc" -struct rsnd_dvc_cfg { - unsigned int max; - unsigned int size; - u32 *val; - const char * const *texts; -}; - -struct rsnd_dvc_cfg_m { - struct rsnd_dvc_cfg cfg; - u32 val[RSND_DVC_CHANNELS]; -}; - -struct rsnd_dvc_cfg_s { - struct rsnd_dvc_cfg cfg; - u32 val; -}; - struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - struct rsnd_dvc_cfg_m volume; - struct rsnd_dvc_cfg_m mute; - struct rsnd_dvc_cfg_s ren; /* Ramp Enable */ - struct rsnd_dvc_cfg_s rup; /* Ramp Rate Up */ - struct rsnd_dvc_cfg_s rdown; /* Ramp Rate Down */ + struct rsnd_kctrl_cfg_m volume; + struct rsnd_kctrl_cfg_m mute; + struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ + struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */ + struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ }; #define rsnd_mod_to_dvc(_mod) \ @@ -222,140 +204,6 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, return 0; } -static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_info *uinfo) -{ - struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; - - if (cfg->texts) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = cfg->size; - uinfo->value.enumerated.items = cfg->max; - if (uinfo->value.enumerated.item >= cfg->max) - uinfo->value.enumerated.item = cfg->max - 1; - strlcpy(uinfo->value.enumerated.name, - cfg->texts[uinfo->value.enumerated.item], - sizeof(uinfo->value.enumerated.name)); - } else { - uinfo->count = cfg->size; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = cfg->max; - uinfo->type = (cfg->max == 1) ? - SNDRV_CTL_ELEM_TYPE_BOOLEAN : - SNDRV_CTL_ELEM_TYPE_INTEGER; - } - - return 0; -} - -static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_value *ucontrol) -{ - struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; - int i; - - for (i = 0; i < cfg->size; i++) - if (cfg->texts) - ucontrol->value.enumerated.item[i] = cfg->val[i]; - else - ucontrol->value.integer.value[i] = cfg->val[i]; - - return 0; -} - -static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_value *ucontrol) -{ - struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; - int i, change = 0; - - for (i = 0; i < cfg->size; i++) { - if (cfg->texts) { - change |= (ucontrol->value.enumerated.item[i] != cfg->val[i]); - cfg->val[i] = ucontrol->value.enumerated.item[i]; - } else { - change |= (ucontrol->value.integer.value[i] != cfg->val[i]); - cfg->val[i] = ucontrol->value.integer.value[i]; - } - } - - if (change) - rsnd_dvc_volume_update(mod); - - return change; -} - -static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - struct rsnd_dvc_cfg *private) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_kcontrol *kctrl; - struct snd_kcontrol_new knew = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = name, - .info = rsnd_dvc_volume_info, - .get = rsnd_dvc_volume_get, - .put = rsnd_dvc_volume_put, - .private_value = (unsigned long)private, - }; - int ret; - - kctrl = snd_ctl_new1(&knew, mod); - if (!kctrl) - return -ENOMEM; - - ret = snd_ctl_add(card, kctrl); - if (ret < 0) - return ret; - - return 0; -} - -static int _rsnd_dvc_pcm_new_m(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - struct rsnd_dvc_cfg_m *private, - u32 max) -{ - private->cfg.max = max; - private->cfg.size = RSND_DVC_CHANNELS; - private->cfg.val = private->val; - return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); -} - -static int _rsnd_dvc_pcm_new_s(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - struct rsnd_dvc_cfg_s *private, - u32 max) -{ - private->cfg.max = max; - private->cfg.size = 1; - private->cfg.val = &private->val; - return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); -} - -static int _rsnd_dvc_pcm_new_e(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - struct rsnd_dvc_cfg_s *private, - const char * const *texts, - u32 max) -{ - private->cfg.max = max; - private->cfg.size = 1; - private->cfg.val = &private->val; - private->cfg.texts = texts; - return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); -} - static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd) @@ -365,41 +213,46 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, int ret; /* Volume */ - ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd, + ret = rsnd_kctrl_new_m(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Playback Volume" : "DVC In Capture Volume", + rsnd_dvc_volume_update, &dvc->volume, 0x00800000 - 1); if (ret < 0) return ret; /* Mute */ - ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd, + ret = rsnd_kctrl_new_m(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Mute Switch" : "DVC In Mute Switch", + rsnd_dvc_volume_update, &dvc->mute, 1); if (ret < 0) return ret; /* Ramp */ - ret = _rsnd_dvc_pcm_new_s(mod, rdai, rtd, + ret = rsnd_kctrl_new_s(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Ramp Switch" : "DVC In Ramp Switch", + rsnd_dvc_volume_update, &dvc->ren, 1); if (ret < 0) return ret; - ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd, + ret = rsnd_kctrl_new_e(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", &dvc->rup, + rsnd_dvc_volume_update, dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); if (ret < 0) return ret; - ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd, + ret = rsnd_kctrl_new_e(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", &dvc->rdown, + rsnd_dvc_volume_update, dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); if (ret < 0) diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 48999b1..133ba1f 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -418,6 +418,51 @@ struct rsnd_priv { }) /* + * rsnd_kctrl + */ +struct rsnd_kctrl_cfg { + unsigned int max; + unsigned int size; + u32 *val; + const char * const *texts; + void (*update)(struct rsnd_mod *mod); +}; + +#define RSND_DVC_CHANNELS 2 +struct rsnd_kctrl_cfg_m { + struct rsnd_kctrl_cfg cfg; + u32 val[RSND_DVC_CHANNELS]; +}; + +struct rsnd_kctrl_cfg_s { + struct rsnd_kctrl_cfg cfg; + u32 val; +}; + +int rsnd_kctrl_new_m(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + void (*update)(struct rsnd_mod *mod), + struct rsnd_kctrl_cfg_m *_cfg, + u32 max); +int rsnd_kctrl_new_s(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + void (*update)(struct rsnd_mod *mod), + struct rsnd_kctrl_cfg_s *_cfg, + u32 max); +int rsnd_kctrl_new_e(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + struct rsnd_kctrl_cfg_s *_cfg, + void (*update)(struct rsnd_mod *mod), + const char * const *texts, + u32 max); + +/* * R-Car SRC */ int rsnd_src_probe(struct platform_device *pdev, -- cgit v0.10.2 From 0cf7718520dcd673d385105d92a6b1ab923ee373 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:06:25 +0000 Subject: ASoC: rsnd: tidyup rsnd_io_to_runtime() macro Avoid NULL pointer access Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 133ba1f..5826c8a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -303,7 +303,8 @@ struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id); int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai); #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) -#define rsnd_io_to_runtime(io) ((io)->substream->runtime) +#define rsnd_io_to_runtime(io) ((io)->substream ? \ + (io)->substream->runtime : NULL) void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); -- cgit v0.10.2 From b167a5780cacb602dfbd3d6f853d7ce916df3fb0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:06:34 +0000 Subject: ASoC: rsnd: use rsnd_src_convert_rate() once on rsnd_src_set_convert_rate_gen2() using many rsnd_src_convert_rate() is not readable. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index c301195..0a56ccd 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -525,16 +525,17 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct rsnd_src *src = rsnd_mod_to_src(mod); + u32 convert_rate = rsnd_src_convert_rate(src); uint ratio; int ret; /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ - if (!rsnd_src_convert_rate(src)) + if (!convert_rate) ratio = 0; - else if (rsnd_src_convert_rate(src) > runtime->rate) - ratio = 100 * rsnd_src_convert_rate(src) / runtime->rate; + else if (convert_rate > runtime->rate) + ratio = 100 * convert_rate / runtime->rate; else - ratio = 100 * runtime->rate / rsnd_src_convert_rate(src); + ratio = 100 * runtime->rate / convert_rate; if (ratio > 600) { dev_err(dev, "FSO/FSI ratio error\n"); -- cgit v0.10.2 From 603cefa59b1aed460f5fdcb1b6af32efc7e6d82f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:06:43 +0000 Subject: ASoC: rsnd: initialize SRC on rsnd_src_init() Current src initialize SRC on rsnd_src_set_convert_rate() but, it should be done on rsnd_src_init(). Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 0a56ccd..6a63f8f 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -256,12 +256,6 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, rsnd_mod_write(mod, SRC_SWRSR, 0); rsnd_mod_write(mod, SRC_SWRSR, 1); - /* - * Initialize the operation of the SRC internal circuits - * see rsnd_src_start() - */ - rsnd_mod_write(mod, SRC_SRCIR, 1); - /* Set channel number and output bit length */ rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); @@ -286,6 +280,12 @@ static int rsnd_src_init(struct rsnd_mod *mod, clk_prepare_enable(src->clk); + /* + * Initialize the operation of the SRC internal circuits + * see rsnd_src_start() + */ + rsnd_mod_write(mod, SRC_SRCIR, 1); + return 0; } @@ -306,7 +306,7 @@ static int rsnd_src_start(struct rsnd_mod *mod, /* * Cancel the initialization and operate the SRC function - * see rsnd_src_set_convert_rate() + * see rsnd_src_init() */ rsnd_mod_write(mod, SRC_SRCIR, 0); -- cgit v0.10.2 From 933cc8cb08d867459689662cf67017ea6f0c6b53 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:07:07 +0000 Subject: ASoC: rsnd: set SRC_ROUTE_MODE0 on each rsnd_src_set_convert_rate() Current src.c sets SRC_ROUTE_MODE0 on rsnd_src_start(), but, set it in rsnd_src_set_convert_rate() is natural. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 6a63f8f..0b6b230 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -302,17 +302,12 @@ static int rsnd_src_quit(struct rsnd_mod *mod, static int rsnd_src_start(struct rsnd_mod *mod, struct rsnd_dai *rdai) { - struct rsnd_src *src = rsnd_mod_to_src(mod); - /* * Cancel the initialization and operate the SRC function * see rsnd_src_init() */ rsnd_mod_write(mod, SRC_SRCIR, 0); - if (rsnd_src_convert_rate(src)) - rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); - return 0; } @@ -320,11 +315,7 @@ static int rsnd_src_start(struct rsnd_mod *mod, static int rsnd_src_stop(struct rsnd_mod *mod, struct rsnd_dai *rdai) { - struct rsnd_src *src = rsnd_mod_to_src(mod); - - if (rsnd_src_convert_rate(src)) - rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0); - + /* nothing to do */ return 0; } @@ -431,6 +422,7 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, struct rsnd_dai *rdai) { + struct rsnd_src *src = rsnd_mod_to_src(mod); int ret; ret = rsnd_src_set_convert_rate(mod, rdai); @@ -444,6 +436,10 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, rsnd_mod_write(mod, SRC_MNFSR, rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); + /* Gen1/Gen2 are not compatible */ + if (rsnd_src_convert_rate(src)) + rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); + /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ return 0; @@ -548,6 +544,11 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); + if (convert_rate) { + /* Gen1/Gen2 are not compatible */ + rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); + } + switch (rsnd_mod_id(mod)) { case 5: case 6: -- cgit v0.10.2 From 49229850bee539e94f0c085a0f89cbbda7f6074b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:07:17 +0000 Subject: ASoC: rsnd: share SSI starting method between PIO/DMA mode Basically, SSI starting method is same between PIO/DMA mode. Let's share it Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 292e98b..5af016e 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -412,8 +412,8 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, return ret; } -static int rsnd_ssi_pio_start(struct rsnd_mod *mod, - struct rsnd_dai *rdai) +static int rsnd_ssi_start(struct rsnd_mod *mod, + struct rsnd_dai *rdai) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); @@ -427,8 +427,8 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, return 0; } -static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, - struct rsnd_dai *rdai) +static int rsnd_ssi_stop(struct rsnd_mod *mod, + struct rsnd_dai *rdai) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); @@ -448,8 +448,8 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { .probe = rsnd_ssi_pio_probe, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, - .start = rsnd_ssi_pio_start, - .stop = rsnd_ssi_pio_stop, + .start = rsnd_ssi_start, + .stop = rsnd_ssi_stop, }; static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, @@ -508,13 +508,9 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod, static int rsnd_ssi_dma_start(struct rsnd_mod *mod, struct rsnd_dai *rdai) { - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - - rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - rsnd_ssi_hw_start(ssi, ssi->rdai, io); + rsnd_ssi_start(mod, rdai); rsnd_dma_start(dma); @@ -524,16 +520,11 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, struct rsnd_dai *rdai) { - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); rsnd_dma_stop(dma); - rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); - - rsnd_ssi_hw_stop(ssi, rdai); - - rsnd_src_ssiu_stop(mod, rdai); + rsnd_ssi_stop(mod, rdai); return 0; } -- cgit v0.10.2 From f0ef0cb84b4351601e696705c0be9cd54e264d81 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:07:28 +0000 Subject: ASoC: rsnd: remove un-necessary parameter from rsnd_src_start/stop() rsnd_src_start/stop() requests struct rsnd_dai as parameter. but, it is not used, and become more complex in L/R error handling. Let's remove it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 0b6b230..eede3ac 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -299,8 +299,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod, return 0; } -static int rsnd_src_start(struct rsnd_mod *mod, - struct rsnd_dai *rdai) +static int rsnd_src_start(struct rsnd_mod *mod) { /* * Cancel the initialization and operate the SRC function @@ -311,9 +310,7 @@ static int rsnd_src_start(struct rsnd_mod *mod, return 0; } - -static int rsnd_src_stop(struct rsnd_mod *mod, - struct rsnd_dai *rdai) +static int rsnd_src_stop(struct rsnd_mod *mod) { /* nothing to do */ return 0; @@ -488,7 +485,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod, rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); - return rsnd_src_start(mod, rdai); + return rsnd_src_start(mod); } static int rsnd_src_stop_gen1(struct rsnd_mod *mod, @@ -498,7 +495,7 @@ static int rsnd_src_stop_gen1(struct rsnd_mod *mod, rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); - return rsnd_src_stop(mod, rdai); + return rsnd_src_stop(mod); } static struct rsnd_mod_ops rsnd_src_gen1_ops = { @@ -646,7 +643,7 @@ static int rsnd_src_start_gen2(struct rsnd_mod *mod, rsnd_mod_write(mod, SRC_CTRL, val); - return rsnd_src_start(mod, rdai); + return rsnd_src_start(mod); } static int rsnd_src_stop_gen2(struct rsnd_mod *mod, @@ -658,7 +655,7 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); - return rsnd_src_stop(mod, rdai); + return rsnd_src_stop(mod); } static struct rsnd_mod_ops rsnd_src_gen2_ops = { -- cgit v0.10.2 From 4e7d606cd52aa8997805b44a50065a7f74cd2953 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:07:47 +0000 Subject: ASoC: rsnd: add salvage support for under/over flow error on SSI L/R channel will be switched if under/over flow error happen on Renesas R-Car sound device by the HW bugs. Then, HW restart is required for salvage. This patch add salvage support for SSI. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 5af016e..6f7080b 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -202,14 +202,14 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, } cr_mode = rsnd_ssi_is_dma_mode(&ssi->mod) ? - DMEN : /* DMA : use DMA */ - UIEN | OIEN | DIEN; /* PIO : enable interrupt */ + DMEN : /* DMA : enable DMA */ + DIEN; /* PIO : enable Data interrupt */ cr = ssi->cr_own | ssi->cr_clk | cr_mode | - EN; + UIEN | OIEN | EN; rsnd_mod_write(&ssi->mod, SSICR, cr); @@ -355,22 +355,54 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) /* * SSI PIO */ +static int rsnd_ssi_start(struct rsnd_mod *mod, + struct rsnd_dai *rdai) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + + rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); + + rsnd_ssi_hw_start(ssi, rdai, io); + + rsnd_src_ssi_irq_enable(mod, rdai); + + return 0; +} + +static int rsnd_ssi_stop(struct rsnd_mod *mod, + struct rsnd_dai *rdai) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + + rsnd_src_ssi_irq_disable(mod, rdai); + + rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); + + rsnd_ssi_hw_stop(ssi, rdai); + + rsnd_src_ssiu_stop(mod, rdai); + + return 0; +} + static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) { struct rsnd_ssi *ssi = data; + struct rsnd_dai *rdai = ssi->rdai; struct rsnd_mod *mod = &ssi->mod; struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); u32 status = rsnd_mod_read(mod, SSISR); - irqreturn_t ret = IRQ_NONE; - if (io && (status & DIRQ)) { - struct rsnd_dai *rdai = ssi->rdai; + if (!io) + return IRQ_NONE; + + /* PIO only */ + if (status & DIRQ) { struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); u32 *buf = (u32 *)(runtime->dma_area + rsnd_dai_pointer_offset(io, 0)); - rsnd_ssi_record_error(ssi, status); - /* * 8/16/32 data can be assesse to TDR/RDR register * directly as 32bit data @@ -382,11 +414,26 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) *buf = rsnd_mod_read(mod, SSIRDR); rsnd_dai_pointer_update(io, sizeof(*buf)); + } - ret = IRQ_HANDLED; + /* PIO / DMA */ + if (status & (UIRQ | OIRQ)) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); + + /* + * restart SSI + */ + rsnd_ssi_stop(mod, rdai); + rsnd_ssi_start(mod, rdai); + + dev_dbg(dev, "%s[%d] restart\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); } - return ret; + rsnd_ssi_record_error(ssi, status); + + return IRQ_HANDLED; } static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, @@ -412,37 +459,6 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, return ret; } -static int rsnd_ssi_start(struct rsnd_mod *mod, - struct rsnd_dai *rdai) -{ - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - - rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); - - rsnd_ssi_hw_start(ssi, rdai, io); - - rsnd_src_ssi_irq_enable(mod, rdai); - - return 0; -} - -static int rsnd_ssi_stop(struct rsnd_mod *mod, - struct rsnd_dai *rdai) -{ - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - - rsnd_src_ssi_irq_disable(mod, rdai); - - rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); - - rsnd_ssi_hw_stop(ssi, rdai); - - rsnd_src_ssiu_stop(mod, rdai); - - return 0; -} - static struct rsnd_mod_ops rsnd_ssi_pio_ops = { .name = SSI_NAME, .probe = rsnd_ssi_pio_probe, @@ -461,17 +477,28 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, int dma_id = ssi->info->dma_id; int ret; + ret = devm_request_irq(dev, ssi->info->pio_irq, + rsnd_ssi_pio_interrupt, + IRQF_SHARED, + dev_name(dev), ssi); + if (ret) + goto rsnd_ssi_dma_probe_fail; + ret = rsnd_dma_init( priv, rsnd_mod_to_dma(mod), rsnd_info_is_playback(priv, ssi), dma_id); + if (ret) + goto rsnd_ssi_dma_probe_fail; - if (ret < 0) - dev_err(dev, "%s[%d] (DMA) is failed\n", - rsnd_mod_name(mod), rsnd_mod_id(mod)); - else - dev_dbg(dev, "%s[%d] (DMA) is probed\n", - rsnd_mod_name(mod), rsnd_mod_id(mod)); + dev_dbg(dev, "%s[%d] (DMA) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + + return ret; + +rsnd_ssi_dma_probe_fail: + dev_err(dev, "%s[%d] (DMA) is failed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } @@ -479,8 +506,16 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct rsnd_dai *rdai) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct device *dev = rsnd_priv_to_dev(priv); + int irq = ssi->info->pio_irq; + rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); + /* PIO will request IRQ again */ + devm_free_irq(dev, irq, ssi); + return 0; } -- cgit v0.10.2 From 6cfad789610342443923737a9def8b637151dc4d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Nov 2014 08:08:10 +0000 Subject: ASoC: rsnd: rename SSI function name of PIO Current R-Car sound SSI PIO/DMA mode are using interrupt. it is no longer "xxx_pio_xxx", rename it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h index d76412b..83284ca 100644 --- a/include/sound/rcar_snd.h +++ b/include/sound/rcar_snd.h @@ -36,14 +36,14 @@ #define RSND_SSI_CLK_PIN_SHARE (1 << 31) #define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */ -#define RSND_SSI(_dma_id, _pio_irq, _flags) \ -{ .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } +#define RSND_SSI(_dma_id, _irq, _flags) \ +{ .dma_id = _dma_id, .irq = _irq, .flags = _flags } #define RSND_SSI_UNUSED \ -{ .dma_id = -1, .pio_irq = -1, .flags = 0 } +{ .dma_id = -1, .irq = -1, .flags = 0 } struct rsnd_ssi_platform_info { int dma_id; - int pio_irq; + int irq; u32 flags; }; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 6f7080b..3844fbe 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -82,7 +82,7 @@ struct rsnd_ssi { #define rsnd_ssi_nr(priv) ((priv)->ssi_nr) #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) #define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma)) -#define rsnd_ssi_pio_available(ssi) ((ssi)->info->pio_irq > 0) +#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) #define rsnd_ssi_dma_available(ssi) \ rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod)) #define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) @@ -352,9 +352,6 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) } } -/* - * SSI PIO - */ static int rsnd_ssi_start(struct rsnd_mod *mod, struct rsnd_dai *rdai) { @@ -386,7 +383,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, return 0; } -static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) +static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) { struct rsnd_ssi *ssi = data; struct rsnd_dai *rdai = ssi->rdai; @@ -436,17 +433,19 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) return IRQ_HANDLED; } +/* + * SSI PIO + */ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, struct rsnd_dai *rdai) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - int irq = ssi->info->pio_irq; int ret; - ret = devm_request_irq(dev, irq, - rsnd_ssi_pio_interrupt, + ret = devm_request_irq(dev, ssi->info->irq, + rsnd_ssi_interrupt, IRQF_SHARED, dev_name(dev), ssi); if (ret) @@ -477,8 +476,8 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, int dma_id = ssi->info->dma_id; int ret; - ret = devm_request_irq(dev, ssi->info->pio_irq, - rsnd_ssi_pio_interrupt, + ret = devm_request_irq(dev, ssi->info->irq, + rsnd_ssi_interrupt, IRQF_SHARED, dev_name(dev), ssi); if (ret) @@ -509,7 +508,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct device *dev = rsnd_priv_to_dev(priv); - int irq = ssi->info->pio_irq; + int irq = ssi->info->irq; rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); @@ -680,7 +679,7 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev, /* * irq */ - ssi_info->pio_irq = irq_of_parse_and_map(np, 0); + ssi_info->irq = irq_of_parse_and_map(np, 0); /* * DMA -- cgit v0.10.2