Merge remote-tracking branches 'asoc/topic/rt5645', 'asoc/topic/rt5677', 'asoc/topic/samsung', 'asoc/topic/sgtl5000' and 'asoc/topic/sh' into asoc-next
This commit is contained in:
Коммит
7370780cfd
|
@ -0,0 +1,59 @@
|
|||
RT5677 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "realtek,rt5677".
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
- interrupts : The CODEC's interrupt output.
|
||||
|
||||
- gpio-controller : Indicates this device is a GPIO controller.
|
||||
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and the
|
||||
second cell is used to specify optional parameters (currently unused).
|
||||
|
||||
Optional properties:
|
||||
|
||||
- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
|
||||
|
||||
- realtek,in1-differential
|
||||
- realtek,in2-differential
|
||||
- realtek,lout1-differential
|
||||
- realtek,lout2-differential
|
||||
- realtek,lout3-differential
|
||||
Boolean. Indicate MIC1/2 input and LOUT1/2/3 outputs are differential,
|
||||
rather than single-ended.
|
||||
|
||||
Pins on the device (for linking into audio routes):
|
||||
|
||||
* IN1P
|
||||
* IN1N
|
||||
* IN2P
|
||||
* IN2N
|
||||
* MICBIAS1
|
||||
* DMIC1
|
||||
* DMIC2
|
||||
* DMIC3
|
||||
* DMIC4
|
||||
* LOUT1
|
||||
* LOUT2
|
||||
* LOUT3
|
||||
|
||||
Example:
|
||||
|
||||
rt5677 {
|
||||
compatible = "realtek,rt5677";
|
||||
reg = <0x2c>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
realtek,pow-ldo2-gpio =
|
||||
<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
|
||||
realtek,in1-differential = "true";
|
||||
};
|
|
@ -20,6 +20,9 @@ struct rt5645_platform_data {
|
|||
/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
|
||||
unsigned int dmic2_data_pin;
|
||||
/* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */
|
||||
|
||||
unsigned int hp_det_gpio;
|
||||
bool gpio_hp_det_active_high;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,9 +19,12 @@ enum rt5677_dmic2_clk {
|
|||
|
||||
|
||||
struct rt5677_platform_data {
|
||||
/* IN1 IN2 can optionally be differential */
|
||||
/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
|
||||
bool in1_diff;
|
||||
bool in2_diff;
|
||||
bool lout1_diff;
|
||||
bool lout2_diff;
|
||||
bool lout3_diff;
|
||||
/* DMIC2 clock source selection */
|
||||
enum rt5677_dmic2_clk dmic2_clk_pin;
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
@ -2103,6 +2104,77 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rt5645_jack_detect(struct snd_soc_codec *codec,
|
||||
struct snd_soc_jack *jack)
|
||||
{
|
||||
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
|
||||
int gpio_state, jack_type = 0;
|
||||
unsigned int val;
|
||||
|
||||
gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio);
|
||||
|
||||
dev_dbg(codec->dev, "gpio = %d(%d)\n", rt5645->pdata.hp_det_gpio,
|
||||
gpio_state);
|
||||
|
||||
if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) ||
|
||||
(!rt5645->pdata.gpio_hp_det_active_high && !gpio_state)) {
|
||||
snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias1");
|
||||
snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias2");
|
||||
snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
|
||||
snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power");
|
||||
snd_soc_dapm_sync(&codec->dapm);
|
||||
|
||||
snd_soc_write(codec, RT5645_IN1_CTRL1, 0x0006);
|
||||
snd_soc_write(codec, RT5645_JD_CTRL3, 0x00b0);
|
||||
|
||||
snd_soc_update_bits(codec, RT5645_IN1_CTRL2,
|
||||
RT5645_CBJ_MN_JD, 0);
|
||||
snd_soc_update_bits(codec, RT5645_IN1_CTRL2,
|
||||
RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD);
|
||||
|
||||
msleep(400);
|
||||
val = snd_soc_read(codec, RT5645_IN1_CTRL3) & 0x7;
|
||||
dev_dbg(codec->dev, "val = %d\n", val);
|
||||
|
||||
if (val == 1 || val == 2)
|
||||
jack_type = SND_JACK_HEADSET;
|
||||
else
|
||||
jack_type = SND_JACK_HEADPHONE;
|
||||
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "micbias1");
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "micbias2");
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "LDO2");
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
|
||||
snd_soc_dapm_sync(&codec->dapm);
|
||||
}
|
||||
|
||||
snd_soc_jack_report(rt5645->jack, jack_type, SND_JACK_HEADSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt5645_set_jack_detect(struct snd_soc_codec *codec,
|
||||
struct snd_soc_jack *jack)
|
||||
{
|
||||
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
rt5645->jack = jack;
|
||||
|
||||
rt5645_jack_detect(codec, rt5645->jack);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt5645_set_jack_detect);
|
||||
|
||||
static irqreturn_t rt5645_irq(int irq, void *data)
|
||||
{
|
||||
struct rt5645_priv *rt5645 = data;
|
||||
|
||||
rt5645_jack_detect(rt5645->codec, rt5645->jack);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rt5645_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
|
||||
|
@ -2250,6 +2322,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
|
|||
if (rt5645 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rt5645->i2c = i2c;
|
||||
i2c_set_clientdata(i2c, rt5645);
|
||||
|
||||
if (pdata)
|
||||
|
@ -2345,12 +2418,38 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
|
|||
|
||||
}
|
||||
|
||||
if (rt5645->i2c->irq) {
|
||||
ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
|
||||
| IRQF_ONESHOT, "rt5645", rt5645);
|
||||
if (ret)
|
||||
dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
|
||||
}
|
||||
|
||||
if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) {
|
||||
ret = gpio_request(rt5645->pdata.hp_det_gpio, "rt5645");
|
||||
if (ret)
|
||||
dev_err(&i2c->dev, "Fail gpio_request hp_det_gpio\n");
|
||||
|
||||
ret = gpio_direction_input(rt5645->pdata.hp_det_gpio);
|
||||
if (ret)
|
||||
dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n");
|
||||
}
|
||||
|
||||
return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645,
|
||||
rt5645_dai, ARRAY_SIZE(rt5645_dai));
|
||||
}
|
||||
|
||||
static int rt5645_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c);
|
||||
|
||||
if (i2c->irq)
|
||||
free_irq(i2c->irq, rt5645);
|
||||
|
||||
if (gpio_is_valid(rt5645->pdata.hp_det_gpio))
|
||||
gpio_free(rt5645->pdata.hp_det_gpio);
|
||||
|
||||
snd_soc_unregister_codec(&i2c->dev);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2166,6 +2166,8 @@ struct rt5645_priv {
|
|||
struct snd_soc_codec *codec;
|
||||
struct rt5645_platform_data pdata;
|
||||
struct regmap *regmap;
|
||||
struct i2c_client *i2c;
|
||||
struct snd_soc_jack *jack;
|
||||
|
||||
int sysclk;
|
||||
int sysclk_src;
|
||||
|
@ -2178,4 +2180,7 @@ struct rt5645_priv {
|
|||
int pll_out;
|
||||
};
|
||||
|
||||
int rt5645_set_jack_detect(struct snd_soc_codec *codec,
|
||||
struct snd_soc_jack *jack);
|
||||
|
||||
#endif /* __RT5645_H__ */
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -541,6 +542,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
|
|||
static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(st_vol_tlv, -4650, 150, 0);
|
||||
|
||||
/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
|
||||
static unsigned int bst_tlv[] = {
|
||||
|
@ -605,6 +607,10 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
|
|||
RT5677_MONO_ADC_L_VOL_SFT, RT5677_MONO_ADC_R_VOL_SFT, 127, 0,
|
||||
adc_vol_tlv),
|
||||
|
||||
/* Sidetone Control */
|
||||
SOC_SINGLE_TLV("Sidetone Volume", RT5677_SIDETONE_CTRL,
|
||||
RT5677_ST_VOL_SFT, 31, 0, st_vol_tlv),
|
||||
|
||||
/* ADC Boost Volume Control */
|
||||
SOC_DOUBLE_TLV("STO1 ADC Boost Volume", RT5677_STO1_2_ADC_BST,
|
||||
RT5677_STO1_ADC_L_BST_SFT, RT5677_STO1_ADC_R_BST_SFT, 3, 0,
|
||||
|
@ -1993,6 +1999,9 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
|
|||
/* Sidetone Mux */
|
||||
SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
|
||||
&rt5677_sidetone_mux),
|
||||
SND_SOC_DAPM_SUPPLY("Sidetone Power", RT5677_SIDETONE_CTRL,
|
||||
RT5677_ST_EN_SFT, 0, NULL, 0),
|
||||
|
||||
/* VAD Mux*/
|
||||
SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, 0, 0,
|
||||
&rt5677_vad_src_mux),
|
||||
|
@ -2704,6 +2713,7 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
|
|||
{ "Sidetone Mux", "DMIC4 L", "DMIC L4" },
|
||||
{ "Sidetone Mux", "ADC1", "ADC 1" },
|
||||
{ "Sidetone Mux", "ADC2", "ADC 2" },
|
||||
{ "Sidetone Mux", NULL, "Sidetone Power" },
|
||||
|
||||
{ "Stereo DAC MIXL", "ST L Switch", "Sidetone Mux" },
|
||||
{ "Stereo DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" },
|
||||
|
@ -3107,6 +3117,59 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
||||
unsigned int rx_mask, int slots, int slot_width)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
unsigned int val = 0;
|
||||
|
||||
if (rx_mask || tx_mask)
|
||||
val |= (1 << 12);
|
||||
|
||||
switch (slots) {
|
||||
case 4:
|
||||
val |= (1 << 10);
|
||||
break;
|
||||
case 6:
|
||||
val |= (2 << 10);
|
||||
break;
|
||||
case 8:
|
||||
val |= (3 << 10);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (slot_width) {
|
||||
case 20:
|
||||
val |= (1 << 8);
|
||||
break;
|
||||
case 24:
|
||||
val |= (2 << 8);
|
||||
break;
|
||||
case 32:
|
||||
val |= (3 << 8);
|
||||
break;
|
||||
case 16:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dai->id) {
|
||||
case RT5677_AIF1:
|
||||
snd_soc_update_bits(codec, RT5677_TDM1_CTRL1, 0x1f00, val);
|
||||
break;
|
||||
case RT5677_AIF2:
|
||||
snd_soc_update_bits(codec, RT5677_TDM2_CTRL1, 0x1f00, val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt5677_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
|
@ -3316,6 +3379,8 @@ static int rt5677_remove(struct snd_soc_codec *codec)
|
|||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
|
||||
if (gpio_is_valid(rt5677->pow_ldo2))
|
||||
gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3327,6 +3392,8 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
|
|||
|
||||
regcache_cache_only(rt5677->regmap, true);
|
||||
regcache_mark_dirty(rt5677->regmap);
|
||||
if (gpio_is_valid(rt5677->pow_ldo2))
|
||||
gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3335,6 +3402,10 @@ static int rt5677_resume(struct snd_soc_codec *codec)
|
|||
{
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (gpio_is_valid(rt5677->pow_ldo2)) {
|
||||
gpio_set_value_cansleep(rt5677->pow_ldo2, 1);
|
||||
msleep(10);
|
||||
}
|
||||
regcache_cache_only(rt5677->regmap, false);
|
||||
regcache_sync(rt5677->regmap);
|
||||
|
||||
|
@ -3354,6 +3425,7 @@ static struct snd_soc_dai_ops rt5677_aif_dai_ops = {
|
|||
.set_fmt = rt5677_set_dai_fmt,
|
||||
.set_sysclk = rt5677_set_dai_sysclk,
|
||||
.set_pll = rt5677_set_dai_pll,
|
||||
.set_tdm_slot = rt5677_set_tdm_slot,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver rt5677_dai[] = {
|
||||
|
@ -3492,6 +3564,35 @@ static const struct i2c_device_id rt5677_i2c_id[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
|
||||
|
||||
static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
|
||||
{
|
||||
rt5677->pdata.in1_diff = of_property_read_bool(np,
|
||||
"realtek,in1-differential");
|
||||
rt5677->pdata.in2_diff = of_property_read_bool(np,
|
||||
"realtek,in2-differential");
|
||||
rt5677->pdata.lout1_diff = of_property_read_bool(np,
|
||||
"realtek,lout1-differential");
|
||||
rt5677->pdata.lout2_diff = of_property_read_bool(np,
|
||||
"realtek,lout2-differential");
|
||||
rt5677->pdata.lout3_diff = of_property_read_bool(np,
|
||||
"realtek,lout3-differential");
|
||||
|
||||
rt5677->pow_ldo2 = of_get_named_gpio(np,
|
||||
"realtek,pow-ldo2-gpio", 0);
|
||||
|
||||
/*
|
||||
* POW_LDO2 is optional (it may be statically tied on the board).
|
||||
* -ENOENT means that the property doesn't exist, i.e. there is no
|
||||
* GPIO, so is not an error. Any other error code means the property
|
||||
* exists, but could not be parsed.
|
||||
*/
|
||||
if (!gpio_is_valid(rt5677->pow_ldo2) &&
|
||||
(rt5677->pow_ldo2 != -ENOENT))
|
||||
return rt5677->pow_ldo2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt5677_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -3510,6 +3611,33 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
|
|||
if (pdata)
|
||||
rt5677->pdata = *pdata;
|
||||
|
||||
if (i2c->dev.of_node) {
|
||||
ret = rt5677_parse_dt(rt5677, i2c->dev.of_node);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Failed to parse device tree: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
rt5677->pow_ldo2 = -EINVAL;
|
||||
}
|
||||
|
||||
if (gpio_is_valid(rt5677->pow_ldo2)) {
|
||||
ret = devm_gpio_request_one(&i2c->dev, rt5677->pow_ldo2,
|
||||
GPIOF_OUT_INIT_HIGH,
|
||||
"RT5677 POW_LDO2");
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "Failed to request POW_LDO2 %d: %d\n",
|
||||
rt5677->pow_ldo2, ret);
|
||||
return ret;
|
||||
}
|
||||
/* Wait a while until I2C bus becomes available. The datasheet
|
||||
* does not specify the exact we should wait but startup
|
||||
* sequence mentiones at least a few milliseconds.
|
||||
*/
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
rt5677->regmap = devm_regmap_init_i2c(i2c, &rt5677_regmap);
|
||||
if (IS_ERR(rt5677->regmap)) {
|
||||
ret = PTR_ERR(rt5677->regmap);
|
||||
|
@ -3540,6 +3668,18 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
|
|||
regmap_update_bits(rt5677->regmap, RT5677_IN1,
|
||||
RT5677_IN_DF2, RT5677_IN_DF2);
|
||||
|
||||
if (rt5677->pdata.lout1_diff)
|
||||
regmap_update_bits(rt5677->regmap, RT5677_LOUT1,
|
||||
RT5677_LOUT1_L_DF, RT5677_LOUT1_L_DF);
|
||||
|
||||
if (rt5677->pdata.lout2_diff)
|
||||
regmap_update_bits(rt5677->regmap, RT5677_LOUT1,
|
||||
RT5677_LOUT2_L_DF, RT5677_LOUT2_L_DF);
|
||||
|
||||
if (rt5677->pdata.lout3_diff)
|
||||
regmap_update_bits(rt5677->regmap, RT5677_LOUT1,
|
||||
RT5677_LOUT3_L_DF, RT5677_LOUT3_L_DF);
|
||||
|
||||
if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) {
|
||||
regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL2,
|
||||
RT5677_GPIO5_FUNC_MASK,
|
||||
|
|
|
@ -382,6 +382,10 @@
|
|||
#define RT5677_ST_SEL_SFT 9
|
||||
#define RT5677_ST_EN (0x1 << 6)
|
||||
#define RT5677_ST_EN_SFT 6
|
||||
#define RT5677_ST_GAIN (0x1 << 5)
|
||||
#define RT5677_ST_GAIN_SFT 5
|
||||
#define RT5677_ST_VOL_MASK (0x1f << 0)
|
||||
#define RT5677_ST_VOL_SFT 0
|
||||
|
||||
/* Analog DAC1/2/3 Source Control (0x15) */
|
||||
#define RT5677_ANA_DAC3_SRC_SEL_MASK (0x3 << 4)
|
||||
|
@ -1550,6 +1554,7 @@ struct rt5677_priv {
|
|||
int pll_src;
|
||||
int pll_in;
|
||||
int pll_out;
|
||||
int pow_ldo2; /* POW_LDO2 pin */
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
struct gpio_chip gpio_chip;
|
||||
#endif
|
||||
|
|
|
@ -626,6 +626,9 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
|
|||
} else {
|
||||
dev_err(codec->dev,
|
||||
"PLL not supported in slave mode\n");
|
||||
dev_err(codec->dev, "%d ratio is not supported. "
|
||||
"SYS_MCLK needs to be 256, 384 or 512 * fs\n",
|
||||
sgtl5000->sysclk / sys_fs);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -1442,6 +1445,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
|
|||
{
|
||||
struct sgtl5000_priv *sgtl5000;
|
||||
int ret, reg, rev;
|
||||
unsigned int mclk;
|
||||
|
||||
sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv),
|
||||
GFP_KERNEL);
|
||||
|
@ -1465,6 +1469,14 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* SGTL5000 SYS_MCLK should be between 8 and 27 MHz */
|
||||
mclk = clk_get_rate(sgtl5000->mclk);
|
||||
if (mclk < 8000000 || mclk > 27000000) {
|
||||
dev_err(&client->dev, "Invalid SYS_CLK frequency: %u.%03uMHz\n",
|
||||
mclk / 1000000, mclk / 1000 % 1000);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(sgtl5000->mclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -351,7 +351,7 @@ static void idma_free(struct snd_pcm *pcm)
|
|||
if (!buf->area)
|
||||
return;
|
||||
|
||||
iounmap(buf->area);
|
||||
iounmap((void __iomem *)buf->area);
|
||||
|
||||
buf->area = NULL;
|
||||
buf->addr = 0;
|
||||
|
@ -369,7 +369,7 @@ static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream)
|
|||
buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS;
|
||||
buf->addr = idma.lp_tx_addr;
|
||||
buf->bytes = idma_hardware.buffer_bytes_max;
|
||||
buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes);
|
||||
buf->area = (unsigned char * __force)ioremap(buf->addr, buf->bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -66,12 +66,12 @@ static struct snd_soc_card odroidx2 = {
|
|||
.late_probe = odroidx2_late_probe,
|
||||
};
|
||||
|
||||
struct odroidx2_drv_data odroidx2_drvdata = {
|
||||
static const struct odroidx2_drv_data odroidx2_drvdata = {
|
||||
.dapm_widgets = odroidx2_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(odroidx2_dapm_widgets),
|
||||
};
|
||||
|
||||
struct odroidx2_drv_data odroidu3_drvdata = {
|
||||
static const struct odroidx2_drv_data odroidu3_drvdata = {
|
||||
.dapm_widgets = odroidu3_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(odroidu3_dapm_widgets),
|
||||
};
|
||||
|
|
|
@ -1297,9 +1297,14 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
|
|||
struct snd_pcm_substream *substream = io->substream;
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
int is_play = fsi_stream_is_play(fsi, io);
|
||||
enum dma_data_direction dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
|
||||
enum dma_transfer_direction dir;
|
||||
int ret = -EIO;
|
||||
|
||||
if (is_play)
|
||||
dir = DMA_MEM_TO_DEV;
|
||||
else
|
||||
dir = DMA_DEV_TO_MEM;
|
||||
|
||||
desc = dmaengine_prep_dma_cyclic(io->chan,
|
||||
substream->runtime->dma_addr,
|
||||
snd_pcm_lib_buffer_bytes(substream),
|
||||
|
|
|
@ -139,7 +139,7 @@ static int siu_pcm_wr_set(struct siu_port *port_info,
|
|||
|
||||
desc->callback = siu_dma_tx_complete;
|
||||
desc->callback_param = siu_stream;
|
||||
cookie = desc->tx_submit(desc);
|
||||
cookie = dmaengine_submit(desc);
|
||||
if (cookie < 0) {
|
||||
dev_err(dev, "Failed to submit a dma transfer\n");
|
||||
return cookie;
|
||||
|
@ -189,7 +189,7 @@ static int siu_pcm_rd_set(struct siu_port *port_info,
|
|||
|
||||
desc->callback = siu_dma_tx_complete;
|
||||
desc->callback_param = siu_stream;
|
||||
cookie = desc->tx_submit(desc);
|
||||
cookie = dmaengine_submit(desc);
|
||||
if (cookie < 0) {
|
||||
dev_err(dev, "Failed to submit dma descriptor\n");
|
||||
return cookie;
|
||||
|
|
Загрузка…
Ссылка в новой задаче