Skip to content

Commit

Permalink
Merge remote-tracking branches 'asoc/topic/sh', 'asoc/topic/sigmadsp'…
Browse files Browse the repository at this point in the history
…, 'asoc/topic/simple', 'asoc/topic/sirf' and 'asoc/topic/sn95031' into asoc-next
  • Loading branch information
Mark Brown committed Dec 8, 2014
6 parents 4c90877 + caaeb6a + d98123a + 7195d92 + 335ca47 + 0eef4ed commit 631657c
Show file tree
Hide file tree
Showing 13 changed files with 1,007 additions and 147 deletions.
9 changes: 7 additions & 2 deletions Documentation/devicetree/bindings/sound/renesas,fsi.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
Renesas FSI

Required properties:
- compatible : "renesas,sh_fsi2" or "renesas,sh_fsi"
- compatible : "renesas,fsi2-<soctype>",
"renesas,sh_fsi2" or "renesas,sh_fsi" as
fallback.
Examples with soctypes are:
- "renesas,fsi2-r8a7740" (R-Mobile A1)
- "renesas,fsi2-sh73a0" (SH-Mobile AG5)
- reg : Should contain the register physical address and length
- interrupts : Should contain FSI interrupt

- fsia,spdif-connection : FSI is connected by S/PDFI
- fsia,spdif-connection : FSI is connected by S/PDIF
- fsia,stream-mode-support : FSI supports 16bit stream mode.
- fsia,use-internal-clock : FSI uses internal clock when master mode.

Expand Down
86 changes: 81 additions & 5 deletions sound/soc/codecs/adau1701.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include <asm/unaligned.h>

#include "sigmadsp.h"
#include "adau1701.h"

#define ADAU1701_SAFELOAD_DATA(i) (0x0810 + (i))
#define ADAU1701_SAFELOAD_ADDR(i) (0x0815 + (i))

#define ADAU1701_DSPCTRL 0x081c
#define ADAU1701_SEROCTL 0x081e
#define ADAU1701_SERICTL 0x081f
Expand All @@ -42,6 +47,7 @@
#define ADAU1701_DSPCTRL_CR (1 << 2)
#define ADAU1701_DSPCTRL_DAM (1 << 3)
#define ADAU1701_DSPCTRL_ADM (1 << 4)
#define ADAU1701_DSPCTRL_IST (1 << 5)
#define ADAU1701_DSPCTRL_SR_48 0x00
#define ADAU1701_DSPCTRL_SR_96 0x01
#define ADAU1701_DSPCTRL_SR_192 0x02
Expand Down Expand Up @@ -102,7 +108,10 @@ struct adau1701 {
unsigned int pll_clkdiv;
unsigned int sysclk;
struct regmap *regmap;
struct i2c_client *client;
u8 pin_config[12];

struct sigmadsp *sigmadsp;
};

static const struct snd_kcontrol_new adau1701_controls[] = {
Expand Down Expand Up @@ -159,6 +168,7 @@ static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case ADAU1701_DACSET:
case ADAU1701_DSPCTRL:
return true;
default:
return false;
Expand Down Expand Up @@ -238,12 +248,58 @@ static int adau1701_reg_read(void *context, unsigned int reg,
return 0;
}

static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
static int adau1701_safeload(struct sigmadsp *sigmadsp, unsigned int addr,
const uint8_t bytes[], size_t len)
{
struct i2c_client *client = to_i2c_client(sigmadsp->dev);
struct adau1701 *adau1701 = i2c_get_clientdata(client);
unsigned int val;
unsigned int i;
uint8_t buf[10];
int ret;

ret = regmap_read(adau1701->regmap, ADAU1701_DSPCTRL, &val);
if (ret)
return ret;

if (val & ADAU1701_DSPCTRL_IST)
msleep(50);

for (i = 0; i < len / 4; i++) {
put_unaligned_le16(ADAU1701_SAFELOAD_DATA(i), buf);
buf[2] = 0x00;
memcpy(buf + 3, bytes + i * 4, 4);
ret = i2c_master_send(client, buf, 7);
if (ret < 0)
return ret;
else if (ret != 7)
return -EIO;

put_unaligned_le16(ADAU1701_SAFELOAD_ADDR(i), buf);
put_unaligned_le16(addr + i, buf + 2);
ret = i2c_master_send(client, buf, 4);
if (ret < 0)
return ret;
else if (ret != 4)
return -EIO;
}

return regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
ADAU1701_DSPCTRL_IST, ADAU1701_DSPCTRL_IST);
}

static const struct sigmadsp_ops adau1701_sigmadsp_ops = {
.safeload = adau1701_safeload,
};

static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
unsigned int rate)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *client = to_i2c_client(codec->dev);
int ret;

sigmadsp_reset(adau1701->sigmadsp);

if (clkdiv != ADAU1707_CLKDIV_UNSET &&
gpio_is_valid(adau1701->gpio_pll_mode[0]) &&
gpio_is_valid(adau1701->gpio_pll_mode[1])) {
Expand Down Expand Up @@ -284,7 +340,7 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
* know the correct PLL setup
*/
if (clkdiv != ADAU1707_CLKDIV_UNSET) {
ret = process_sigma_firmware(client, ADAU1701_FIRMWARE);
ret = sigmadsp_setup(adau1701->sigmadsp, rate);
if (ret) {
dev_warn(codec->dev, "Failed to load firmware\n");
return ret;
Expand Down Expand Up @@ -385,7 +441,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
* firmware upload.
*/
if (clkdiv != adau1701->pll_clkdiv) {
ret = adau1701_reset(codec, clkdiv);
ret = adau1701_reset(codec, clkdiv, params_rate(params));
if (ret < 0)
return ret;
}
Expand Down Expand Up @@ -554,6 +610,14 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
return 0;
}

static int adau1701_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(dai->codec);

return sigmadsp_restrict_params(adau1701->sigmadsp, substream);
}

#define ADAU1701_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
SNDRV_PCM_RATE_192000)

Expand All @@ -564,6 +628,7 @@ static const struct snd_soc_dai_ops adau1701_dai_ops = {
.set_fmt = adau1701_set_dai_fmt,
.hw_params = adau1701_hw_params,
.digital_mute = adau1701_digital_mute,
.startup = adau1701_startup,
};

static struct snd_soc_dai_driver adau1701_dai = {
Expand Down Expand Up @@ -600,6 +665,10 @@ static int adau1701_probe(struct snd_soc_codec *codec)
unsigned int val;
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);

ret = sigmadsp_attach(adau1701->sigmadsp, &codec->component);
if (ret)
return ret;

/*
* Let the pll_clkdiv variable default to something that won't happen
* at runtime. That way, we can postpone the firmware download from
Expand All @@ -609,7 +678,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;

/* initalize with pre-configured pll mode settings */
ret = adau1701_reset(codec, adau1701->pll_clkdiv);
ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -667,6 +736,7 @@ static int adau1701_i2c_probe(struct i2c_client *client,
if (!adau1701)
return -ENOMEM;

adau1701->client = client;
adau1701->regmap = devm_regmap_init(dev, NULL, client,
&adau1701_regmap);
if (IS_ERR(adau1701->regmap))
Expand Down Expand Up @@ -722,6 +792,12 @@ static int adau1701_i2c_probe(struct i2c_client *client,
adau1701->gpio_pll_mode[1] = gpio_pll_mode[1];

i2c_set_clientdata(client, adau1701);

adau1701->sigmadsp = devm_sigmadsp_init_i2c(client,
&adau1701_sigmadsp_ops, ADAU1701_FIRMWARE);
if (IS_ERR(adau1701->sigmadsp))
return PTR_ERR(adau1701->sigmadsp);

ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
&adau1701_dai, 1);
return ret;
Expand Down
22 changes: 11 additions & 11 deletions sound/soc/codecs/adau1761.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,11 +703,6 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
ARRAY_SIZE(adau1761_dapm_routes));
if (ret)
return ret;

ret = adau17x1_load_firmware(adau, codec->dev,
ADAU1761_FIRMWARE);
if (ret)
dev_warn(codec->dev, "Failed to firmware\n");
}

ret = adau17x1_add_routes(codec);
Expand Down Expand Up @@ -776,16 +771,20 @@ int adau1761_probe(struct device *dev, struct regmap *regmap,
enum adau17x1_type type, void (*switch_mode)(struct device *dev))
{
struct snd_soc_dai_driver *dai_drv;
const char *firmware_name;
int ret;

ret = adau17x1_probe(dev, regmap, type, switch_mode);
if (ret)
return ret;

if (type == ADAU1361)
if (type == ADAU1361) {
dai_drv = &adau1361_dai_driver;
else
firmware_name = NULL;
} else {
dai_drv = &adau1761_dai_driver;
firmware_name = ADAU1761_FIRMWARE;
}

ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
if (ret)
return ret;

return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
}
Expand All @@ -799,6 +798,7 @@ const struct regmap_config adau1761_regmap_config = {
.num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
.readable_reg = adau1761_readable_register,
.volatile_reg = adau17x1_volatile_register,
.precious_reg = adau17x1_precious_register,
.cache_type = REGCACHE_RBTREE,
};
EXPORT_SYMBOL_GPL(adau1761_regmap_config);
Expand Down
31 changes: 14 additions & 17 deletions sound/soc/codecs/adau1781.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
{
struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev);
struct adau *adau = snd_soc_codec_get_drvdata(codec);
const char *firmware;
int ret;

ret = adau17x1_add_widgets(codec);
Expand Down Expand Up @@ -422,25 +421,10 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
return ret;
}

switch (adau->type) {
case ADAU1381:
firmware = ADAU1381_FIRMWARE;
break;
case ADAU1781:
firmware = ADAU1781_FIRMWARE;
break;
default:
return -EINVAL;
}

ret = adau17x1_add_routes(codec);
if (ret < 0)
return ret;

ret = adau17x1_load_firmware(adau, codec->dev, firmware);
if (ret)
dev_warn(codec->dev, "Failed to load firmware\n");

return 0;
}

Expand Down Expand Up @@ -488,16 +472,29 @@ const struct regmap_config adau1781_regmap_config = {
.num_reg_defaults = ARRAY_SIZE(adau1781_reg_defaults),
.readable_reg = adau1781_readable_register,
.volatile_reg = adau17x1_volatile_register,
.precious_reg = adau17x1_precious_register,
.cache_type = REGCACHE_RBTREE,
};
EXPORT_SYMBOL_GPL(adau1781_regmap_config);

int adau1781_probe(struct device *dev, struct regmap *regmap,
enum adau17x1_type type, void (*switch_mode)(struct device *dev))
{
const char *firmware_name;
int ret;

ret = adau17x1_probe(dev, regmap, type, switch_mode);
switch (type) {
case ADAU1381:
firmware_name = ADAU1381_FIRMWARE;
break;
case ADAU1781:
firmware_name = ADAU1781_FIRMWARE;
break;
default:
return -EINVAL;
}

ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
if (ret)
return ret;

Expand Down
Loading

0 comments on commit 631657c

Please sign in to comment.