Merge remote-tracking branches 'asoc/topic/cs42l56', 'asoc/topic/cs42xx8' and 'asoc/topic/davinci' into asoc-next
This commit is contained in:
Коммит
0c5dacf2ca
|
@ -0,0 +1,63 @@
|
|||
CS42L52 audio CODEC
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "cirrus,cs42l56"
|
||||
|
||||
- reg : the I2C address of the device for I2C
|
||||
|
||||
- VA-supply, VCP-supply, VLDO-supply : power supplies for the device,
|
||||
as covered in Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- cirrus,gpio-nreset : GPIO controller's phandle and the number
|
||||
of the GPIO used to reset the codec.
|
||||
|
||||
- cirrus,chgfreq-divisor : Values used to set the Charge Pump Frequency.
|
||||
Allowable values of 0x00 through 0x0F. These are raw values written to the
|
||||
register, not the actual frequency. The frequency is determined by the following.
|
||||
Frequency = MCLK / 4 * (N+2)
|
||||
N = chgfreq_val
|
||||
MCLK = Where MCLK is the frequency of the mclk signal after the MCLKDIV2 circuit.
|
||||
|
||||
- cirrus,ain1a-ref-cfg, ain1b-ref-cfg : boolean, If present, AIN1A or AIN1B are configured
|
||||
as a pseudo-differential input referenced to AIN1REF/AIN3A.
|
||||
|
||||
- cirrus,ain2a-ref-cfg, ain2b-ref-cfg : boolean, If present, AIN2A or AIN2B are configured
|
||||
as a pseudo-differential input referenced to AIN2REF/AIN3B.
|
||||
|
||||
- cirrus,micbias-lvl: Set the output voltage level on the MICBIAS Pin.
|
||||
0 = 0.5 x VA
|
||||
1 = 0.6 x VA
|
||||
2 = 0.7 x VA
|
||||
3 = 0.8 x VA
|
||||
4 = 0.83 x VA
|
||||
5 = 0.91 x VA
|
||||
|
||||
- cirrus,adaptive-pwr-cfg : Configures how the power to the Headphone and Lineout
|
||||
Amplifiers adapt to the output signal levels.
|
||||
0 = Adapt to Volume Mode. Voltage level determined by the sum of the relevant volume settings.
|
||||
1 = Fixed - Headphone and Line Amp supply = + or - VCP/2.
|
||||
2 = Fixed - Headphone and Line Amp supply = + or - VCP.
|
||||
3 = Adapted to Signal; Voltage level is dynamically determined by the output signal.
|
||||
|
||||
- cirrus,hpf-left-freq, hpf-right-freq : Sets the corner frequency (-3dB point) for the internal High-Pass
|
||||
Filter.
|
||||
0 = 1.8Hz
|
||||
1 = 119Hz
|
||||
2 = 236Hz
|
||||
3 = 464Hz
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
codec: codec@4b {
|
||||
compatible = "cirrus,cs42l56";
|
||||
reg = <0x4b>;
|
||||
gpio-reset = <&gpio 10 0>;
|
||||
cirrus,chgfreq-divisor = <0x05>;
|
||||
cirrus.ain1_ref_cfg;
|
||||
cirrus,micbias-lvl = <5>;
|
||||
VA-supply = <®_audio>;
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* linux/sound/cs42l56.h -- Platform data for CS42L56
|
||||
*
|
||||
* Copyright (c) 2014 Cirrus Logic Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __CS42L56_H
|
||||
#define __CS42L56_H
|
||||
|
||||
struct cs42l56_platform_data {
|
||||
|
||||
/* GPIO for Reset */
|
||||
unsigned int gpio_nreset;
|
||||
|
||||
/* MICBIAS Level. Check datasheet Pg48 */
|
||||
unsigned int micbias_lvl;
|
||||
|
||||
/* Analog Input 1A Reference 0=Single 1=Pseudo-Differential */
|
||||
unsigned int ain1a_ref_cfg;
|
||||
|
||||
/* Analog Input 2A Reference 0=Single 1=Pseudo-Differential */
|
||||
unsigned int ain2a_ref_cfg;
|
||||
|
||||
/* Analog Input 1B Reference 0=Single 1=Pseudo-Differential */
|
||||
unsigned int ain1b_ref_cfg;
|
||||
|
||||
/* Analog Input 2B Reference 0=Single 1=Pseudo-Differential */
|
||||
unsigned int ain2b_ref_cfg;
|
||||
|
||||
/* Charge Pump Freq. Check datasheet Pg62 */
|
||||
unsigned int chgfreq;
|
||||
|
||||
/* HighPass Filter Right Channel Corner Frequency */
|
||||
unsigned int hpfb_freq;
|
||||
|
||||
/* HighPass Filter Left Channel Corner Frequency */
|
||||
unsigned int hpfa_freq;
|
||||
|
||||
/* Adaptive Power Control for LO/HP */
|
||||
unsigned int adaptive_pwr;
|
||||
|
||||
};
|
||||
|
||||
#endif /* __CS42L56_H */
|
|
@ -382,6 +382,8 @@ int snd_soc_resume(struct device *dev);
|
|||
int snd_soc_poweroff(struct device *dev);
|
||||
int snd_soc_register_platform(struct device *dev,
|
||||
const struct snd_soc_platform_driver *platform_drv);
|
||||
int devm_snd_soc_register_platform(struct device *dev,
|
||||
const struct snd_soc_platform_driver *platform_drv);
|
||||
void snd_soc_unregister_platform(struct device *dev);
|
||||
int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
|
||||
const struct snd_soc_platform_driver *platform_drv);
|
||||
|
|
|
@ -39,8 +39,9 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_ALC5623 if I2C
|
||||
select SND_SOC_ALC5632 if I2C
|
||||
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
|
||||
select SND_SOC_CS42L51 if I2C
|
||||
select SND_SOC_CS42L52 if I2C
|
||||
select SND_SOC_CS42L51_I2C if I2C
|
||||
select SND_SOC_CS42L52 if I2C && INPUT
|
||||
select SND_SOC_CS42L56 if I2C && INPUT
|
||||
select SND_SOC_CS42L73 if I2C
|
||||
select SND_SOC_CS4270 if I2C
|
||||
select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
|
||||
|
@ -128,7 +129,7 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_WM8955 if I2C
|
||||
select SND_SOC_WM8960 if I2C
|
||||
select SND_SOC_WM8961 if I2C
|
||||
select SND_SOC_WM8962 if I2C
|
||||
select SND_SOC_WM8962 if I2C && INPUT
|
||||
select SND_SOC_WM8971 if I2C
|
||||
select SND_SOC_WM8974 if I2C
|
||||
select SND_SOC_WM8978 if I2C
|
||||
|
@ -281,9 +282,17 @@ config SND_SOC_CQ0093VC
|
|||
config SND_SOC_CS42L51
|
||||
tristate
|
||||
|
||||
config SND_SOC_CS42L51_I2C
|
||||
tristate
|
||||
select SND_SOC_CS42L51
|
||||
|
||||
config SND_SOC_CS42L52
|
||||
tristate "Cirrus Logic CS42L52 CODEC"
|
||||
depends on I2C
|
||||
depends on I2C && INPUT
|
||||
|
||||
config SND_SOC_CS42L56
|
||||
tristate "Cirrus Logic CS42L56 CODEC"
|
||||
depends on I2C && INPUT
|
||||
|
||||
config SND_SOC_CS42L73
|
||||
tristate "Cirrus Logic CS42L73 CODEC"
|
||||
|
@ -603,7 +612,7 @@ config SND_SOC_WM8961
|
|||
|
||||
config SND_SOC_WM8962
|
||||
tristate "Wolfson Microelectronics WM8962 CODEC"
|
||||
depends on I2C
|
||||
depends on I2C && INPUT
|
||||
|
||||
config SND_SOC_WM8971
|
||||
tristate
|
||||
|
|
|
@ -26,7 +26,9 @@ snd-soc-ak5386-objs := ak5386.o
|
|||
snd-soc-arizona-objs := arizona.o
|
||||
snd-soc-cq93vc-objs := cq93vc.o
|
||||
snd-soc-cs42l51-objs := cs42l51.o
|
||||
snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
|
||||
snd-soc-cs42l52-objs := cs42l52.o
|
||||
snd-soc-cs42l56-objs := cs42l56.o
|
||||
snd-soc-cs42l73-objs := cs42l73.o
|
||||
snd-soc-cs4270-objs := cs4270.o
|
||||
snd-soc-cs4271-objs := cs4271.o
|
||||
|
@ -178,7 +180,9 @@ obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
|
|||
obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
|
||||
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L56) += snd-soc-cs42l56.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
|
||||
obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
|
||||
obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* cs42l56.c -- CS42L51 ALSA SoC I2C audio driver
|
||||
*
|
||||
* Copyright 2014 CirrusLogic, Inc.
|
||||
*
|
||||
* Author: Brian Austin <brian.austin@cirrus.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "cs42l51.h"
|
||||
|
||||
static struct i2c_device_id cs42l51_i2c_id[] = {
|
||||
{"cs42l51", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id);
|
||||
|
||||
static int cs42l51_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regmap_config config;
|
||||
|
||||
config = cs42l51_regmap;
|
||||
config.val_bits = 8;
|
||||
config.reg_bits = 8;
|
||||
|
||||
return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config));
|
||||
}
|
||||
|
||||
static int cs42l51_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
snd_soc_unregister_codec(&i2c->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver cs42l51_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "cs42l51",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = cs42l51_i2c_probe,
|
||||
.remove = cs42l51_i2c_remove,
|
||||
.id_table = cs42l51_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(cs42l51_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC CS42L51 I2C Driver");
|
||||
MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -29,7 +29,6 @@
|
|||
#include <sound/initval.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "cs42l51.h"
|
||||
|
@ -483,7 +482,7 @@ static struct snd_soc_dai_driver cs42l51_dai = {
|
|||
.ops = &cs42l51_dai_ops,
|
||||
};
|
||||
|
||||
static int cs42l51_probe(struct snd_soc_codec *codec)
|
||||
static int cs42l51_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
int ret, reg;
|
||||
|
||||
|
@ -504,7 +503,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
|
|||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
|
||||
.probe = cs42l51_probe,
|
||||
.probe = cs42l51_codec_probe,
|
||||
|
||||
.controls = cs42l51_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(cs42l51_snd_controls),
|
||||
|
@ -514,91 +513,56 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
|
|||
.num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
|
||||
};
|
||||
|
||||
static const struct regmap_config cs42l51_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
const struct regmap_config cs42l51_regmap = {
|
||||
.max_register = CS42L51_CHARGE_FREQ,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cs42l51_regmap);
|
||||
|
||||
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
int cs42l51_probe(struct device *dev, struct regmap *regmap)
|
||||
{
|
||||
struct cs42l51_private *cs42l51;
|
||||
struct regmap *regmap;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap);
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
dev_err(&i2c_client->dev, "Failed to create regmap: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
cs42l51 = devm_kzalloc(dev, sizeof(struct cs42l51_private),
|
||||
GFP_KERNEL);
|
||||
if (!cs42l51)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, cs42l51);
|
||||
|
||||
/* Verify that we have a CS42L51 */
|
||||
ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to read I2C\n");
|
||||
dev_err(dev, "failed to read I2C\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
|
||||
(val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
|
||||
dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val);
|
||||
dev_err(dev, "Invalid chip id: %x\n", val);
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n",
|
||||
val & CS42L51_CHIP_REV_MASK);
|
||||
|
||||
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
|
||||
val & 7);
|
||||
|
||||
cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
|
||||
GFP_KERNEL);
|
||||
if (!cs42l51)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c_client, cs42l51);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c_client->dev,
|
||||
ret = snd_soc_register_codec(dev,
|
||||
&soc_codec_device_cs42l51, &cs42l51_dai, 1);
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs42l51_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id cs42l51_id[] = {
|
||||
{"cs42l51", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs42l51_id);
|
||||
EXPORT_SYMBOL_GPL(cs42l51_probe);
|
||||
|
||||
static const struct of_device_id cs42l51_of_match[] = {
|
||||
{ .compatible = "cirrus,cs42l51", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cs42l51_of_match);
|
||||
|
||||
static struct i2c_driver cs42l51_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "cs42l51-codec",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = cs42l51_of_match,
|
||||
},
|
||||
.id_table = cs42l51_id,
|
||||
.probe = cs42l51_i2c_probe,
|
||||
.remove = cs42l51_i2c_remove,
|
||||
};
|
||||
|
||||
module_i2c_driver(cs42l51_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
|
||||
MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -18,9 +18,15 @@
|
|||
#ifndef _CS42L51_H
|
||||
#define _CS42L51_H
|
||||
|
||||
struct device;
|
||||
|
||||
extern const struct regmap_config cs42l51_regmap;
|
||||
int cs42l51_probe(struct device *dev, struct regmap *regmap);
|
||||
|
||||
#define CS42L51_CHIP_ID 0x1B
|
||||
#define CS42L51_CHIP_REV_A 0x00
|
||||
#define CS42L51_CHIP_REV_B 0x01
|
||||
#define CS42L51_CHIP_REV_MASK 0x07
|
||||
|
||||
#define CS42L51_CHIP_REV_ID 0x01
|
||||
#define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b))
|
||||
|
|
|
@ -50,11 +50,9 @@ struct cs42l52_private {
|
|||
u8 mclksel;
|
||||
u32 mclk;
|
||||
u8 flags;
|
||||
#if IS_ENABLED(CONFIG_INPUT)
|
||||
struct input_dev *beep;
|
||||
struct work_struct beep_work;
|
||||
int beep_rate;
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct reg_default cs42l52_reg_defaults[] = {
|
||||
|
@ -962,7 +960,6 @@ static int cs42l52_resume(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT)
|
||||
static int beep_rates[] = {
|
||||
261, 522, 585, 667, 706, 774, 889, 1000,
|
||||
1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
|
||||
|
@ -1096,15 +1093,6 @@ static void cs42l52_free_beep(struct snd_soc_codec *codec)
|
|||
snd_soc_update_bits(codec, CS42L52_BEEP_TONE_CTL,
|
||||
CS42L52_BEEP_EN_MASK, 0);
|
||||
}
|
||||
#else
|
||||
static void cs42l52_init_beep(struct snd_soc_codec *codec)
|
||||
{
|
||||
}
|
||||
|
||||
static void cs42l52_free_beep(struct snd_soc_codec *codec)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cs42l52_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* cs42l52.h -- CS42L56 ALSA SoC audio driver
|
||||
*
|
||||
* Copyright 2014 CirrusLogic, Inc.
|
||||
*
|
||||
* Author: Brian Austin <brian.austin@cirrus.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CS42L56_H__
|
||||
#define __CS42L56_H__
|
||||
|
||||
#define CS42L56_CHIP_ID_1 0x01
|
||||
#define CS42L56_CHIP_ID_2 0x02
|
||||
#define CS42L56_PWRCTL_1 0x03
|
||||
#define CS42L56_PWRCTL_2 0x04
|
||||
#define CS42L56_CLKCTL_1 0x05
|
||||
#define CS42L56_CLKCTL_2 0x06
|
||||
#define CS42L56_SERIAL_FMT 0x07
|
||||
#define CS42L56_CLASSH_CTL 0x08
|
||||
#define CS42L56_MISC_CTL 0x09
|
||||
#define CS42L56_INT_STATUS 0x0a
|
||||
#define CS42L56_PLAYBACK_CTL 0x0b
|
||||
#define CS42L56_DSP_MUTE_CTL 0x0c
|
||||
#define CS42L56_ADCA_MIX_VOLUME 0x0d
|
||||
#define CS42L56_ADCB_MIX_VOLUME 0x0e
|
||||
#define CS42L56_PCMA_MIX_VOLUME 0x0f
|
||||
#define CS42L56_PCMB_MIX_VOLUME 0x10
|
||||
#define CS42L56_ANAINPUT_ADV_VOLUME 0x11
|
||||
#define CS42L56_DIGINPUT_ADV_VOLUME 0x12
|
||||
#define CS42L56_MASTER_A_VOLUME 0x13
|
||||
#define CS42L56_MASTER_B_VOLUME 0x14
|
||||
#define CS42L56_BEEP_FREQ_ONTIME 0x15
|
||||
#define CS42L56_BEEP_FREQ_OFFTIME 0x16
|
||||
#define CS42L56_BEEP_TONE_CFG 0x17
|
||||
#define CS42L56_TONE_CTL 0x18
|
||||
#define CS42L56_CHAN_MIX_SWAP 0x19
|
||||
#define CS42L56_AIN_REFCFG_ADC_MUX 0x1a
|
||||
#define CS42L56_HPF_CTL 0x1b
|
||||
#define CS42L56_MISC_ADC_CTL 0x1c
|
||||
#define CS42L56_GAIN_BIAS_CTL 0x1d
|
||||
#define CS42L56_PGAA_MUX_VOLUME 0x1e
|
||||
#define CS42L56_PGAB_MUX_VOLUME 0x1f
|
||||
#define CS42L56_ADCA_ATTENUATOR 0x20
|
||||
#define CS42L56_ADCB_ATTENUATOR 0x21
|
||||
#define CS42L56_ALC_EN_ATTACK_RATE 0x22
|
||||
#define CS42L56_ALC_RELEASE_RATE 0x23
|
||||
#define CS42L56_ALC_THRESHOLD 0x24
|
||||
#define CS42L56_NOISE_GATE_CTL 0x25
|
||||
#define CS42L56_ALC_LIM_SFT_ZC 0x26
|
||||
#define CS42L56_AMUTE_HPLO_MUX 0x27
|
||||
#define CS42L56_HPA_VOLUME 0x28
|
||||
#define CS42L56_HPB_VOLUME 0x29
|
||||
#define CS42L56_LOA_VOLUME 0x2a
|
||||
#define CS42L56_LOB_VOLUME 0x2b
|
||||
#define CS42L56_LIM_THRESHOLD_CTL 0x2c
|
||||
#define CS42L56_LIM_CTL_RELEASE_RATE 0x2d
|
||||
#define CS42L56_LIM_ATTACK_RATE 0x2e
|
||||
|
||||
/* Device ID and Rev ID Masks */
|
||||
#define CS42L56_DEVID 0x56
|
||||
#define CS42L56_CHIP_ID_MASK 0xff
|
||||
#define CS42L56_AREV_MASK 0x1c
|
||||
#define CS42L56_MTLREV_MASK 0x03
|
||||
|
||||
/* Power bit masks */
|
||||
#define CS42L56_PDN_ALL_MASK 0x01
|
||||
#define CS42L56_PDN_ADCA_MASK 0x02
|
||||
#define CS42L56_PDN_ADCB_MASK 0x04
|
||||
#define CS42L56_PDN_CHRG_MASK 0x08
|
||||
#define CS42L56_PDN_BIAS_MASK 0x10
|
||||
#define CS42L56_PDN_VBUF_MASK 0x20
|
||||
#define CS42L56_PDN_LOA_MASK 0x03
|
||||
#define CS42L56_PDN_LOB_MASK 0x0c
|
||||
#define CS42L56_PDN_HPA_MASK 0x30
|
||||
#define CS42L56_PDN_HPB_MASK 0xc0
|
||||
|
||||
/* serial port and clk masks */
|
||||
#define CS42L56_MASTER_MODE 1
|
||||
#define CS42L56_SLAVE_MODE 0
|
||||
#define CS42L56_MS_MODE_MASK 0x40
|
||||
#define CS42L56_SCLK_INV 1
|
||||
#define CS42L56_SCLK_INV_MASK 0x20
|
||||
#define CS42L56_SCLK_MCLK_MASK 0x18
|
||||
#define CS42L56_MCLK_PREDIV_MASK 0x04
|
||||
#define CS42L56_MCLK_DIV2_MASK 0x02
|
||||
#define CS42L56_MCLK_DIS_MASK 0x01
|
||||
#define CS42L56_CLK_AUTO_MASK 0x20
|
||||
#define CS42L56_CLK_RATIO_MASK 0x1f
|
||||
#define CS42L56_DIG_FMT_I2S 0
|
||||
#define CS42L56_DIG_FMT_LEFT_J 1
|
||||
#define CS42L56_DIG_FMT_MASK 0x08
|
||||
|
||||
/* Class H and misc ctl masks */
|
||||
#define CS42L56_ADAPT_PWR_MASK 0xc0
|
||||
#define CS42L56_CHRG_FREQ_MASK 0x0f
|
||||
#define CS42L56_DIG_MUX_MASK 0x80
|
||||
#define CS42L56_ANLGSFT_MASK 0x10
|
||||
#define CS42L56_ANLGZC_MASK 0x08
|
||||
#define CS42L56_DIGSFT_MASK 0x04
|
||||
#define CS42L56_FREEZE_MASK 0x01
|
||||
#define CS42L56_MIC_BIAS_MASK 0x03
|
||||
#define CS42L56_HPFA_FREQ_MASK 0x03
|
||||
#define CS42L56_HPFB_FREQ_MASK 0xc0
|
||||
#define CS42L56_AIN1A_REF_MASK 0x10
|
||||
#define CS42L56_AIN2A_REF_MASK 0x40
|
||||
#define CS42L56_AIN1B_REF_MASK 0x20
|
||||
#define CS42L56_AIN2B_REF_MASK 0x80
|
||||
|
||||
/* Playback Capture ctl masks */
|
||||
#define CS42L56_PDN_DSP_MASK 0x80
|
||||
#define CS42L56_DEEMPH_MASK 0x40
|
||||
#define CS42L56_PLYBCK_GANG_MASK 0x10
|
||||
#define CS42L56_PCM_INV_MASK 0x0c
|
||||
#define CS42L56_MUTE 1
|
||||
#define CS42L56_UNMUTE 0
|
||||
#define CS42L56_ADCAMIX_MUTE_MASK 0x40
|
||||
#define CS42L56_ADCBMIX_MUTE_MASK 0x80
|
||||
#define CS42L56_PCMAMIX_MUTE_MASK 0x10
|
||||
#define CS42L56_PCMBMIX_MUTE_MASK 0x20
|
||||
#define CS42L56_MSTB_MUTE_MASK 0x02
|
||||
#define CS42L56_MSTA_MUTE_MASK 0x01
|
||||
#define CS42L56_ADCA_MUTE_MASK 0x01
|
||||
#define CS42L56_ADCB_MUTE_MASK 0x02
|
||||
#define CS42L56_HP_MUTE_MASK 0x80
|
||||
#define CS42L56_LO_MUTE_MASK 0x80
|
||||
|
||||
/* Beep masks */
|
||||
#define CS42L56_BEEP_FREQ_MASK 0xf0
|
||||
#define CS42L56_BEEP_ONTIME_MASK 0x0f
|
||||
#define CS42L56_BEEP_OFFTIME_MASK 0xe0
|
||||
#define CS42L56_BEEP_CFG_MASK 0xc0
|
||||
#define CS42L56_BEEP_TREBCF_MASK 0x18
|
||||
#define CS42L56_BEEP_BASSCF_MASK 0x06
|
||||
#define CS42L56_BEEP_TCEN_MASK 0x01
|
||||
#define CS42L56_BEEP_RATE_SHIFT 4
|
||||
#define CS42L56_BEEP_EN_MASK 0x3f
|
||||
|
||||
|
||||
/* Supported MCLKS */
|
||||
#define CS42L56_MCLK_5P6448MHZ 5644800
|
||||
#define CS42L56_MCLK_6MHZ 6000000
|
||||
#define CS42L56_MCLK_6P144MHZ 6144000
|
||||
#define CS42L56_MCLK_11P2896MHZ 11289600
|
||||
#define CS42L56_MCLK_12MHZ 12000000
|
||||
#define CS42L56_MCLK_12P288MHZ 12288000
|
||||
#define CS42L56_MCLK_22P5792MHZ 22579200
|
||||
#define CS42L56_MCLK_24MHZ 24000000
|
||||
#define CS42L56_MCLK_24P576MHZ 24576000
|
||||
|
||||
/* Clock ratios */
|
||||
#define CS42L56_MCLK_LRCLK_128 0x08
|
||||
#define CS42L56_MCLK_LRCLK_125 0x09
|
||||
#define CS42L56_MCLK_LRCLK_136 0x0b
|
||||
#define CS42L56_MCLK_LRCLK_192 0x0c
|
||||
#define CS42L56_MCLK_LRCLK_187P5 0x0d
|
||||
#define CS42L56_MCLK_LRCLK_256 0x10
|
||||
#define CS42L56_MCLK_LRCLK_250 0x11
|
||||
#define CS42L56_MCLK_LRCLK_272 0x13
|
||||
#define CS42L56_MCLK_LRCLK_384 0x14
|
||||
#define CS42L56_MCLK_LRCLK_375 0x15
|
||||
#define CS42L56_MCLK_LRCLK_512 0x18
|
||||
#define CS42L56_MCLK_LRCLK_500 0x19
|
||||
#define CS42L56_MCLK_LRCLK_544 0x1b
|
||||
#define CS42L56_MCLK_LRCLK_750 0x1c
|
||||
#define CS42L56_MCLK_LRCLK_768 0x1d
|
||||
|
||||
|
||||
#define CS42L56_MAX_REGISTER 0x34
|
||||
|
||||
#endif
|
|
@ -248,8 +248,7 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
u32 ratio = cs42xx8->sysclk / params_rate(params);
|
||||
|
|
|
@ -74,11 +74,9 @@ struct wm8962_priv {
|
|||
struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES];
|
||||
struct notifier_block disable_nb[WM8962_NUM_SUPPLIES];
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT)
|
||||
struct input_dev *beep;
|
||||
struct work_struct beep_work;
|
||||
int beep_rate;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
struct gpio_chip gpio_chip;
|
||||
|
@ -3154,7 +3152,6 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(wm8962_mic_detect);
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT)
|
||||
static int beep_rates[] = {
|
||||
500, 1000, 2000, 4000,
|
||||
};
|
||||
|
@ -3286,15 +3283,6 @@ static void wm8962_free_beep(struct snd_soc_codec *codec)
|
|||
|
||||
snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0);
|
||||
}
|
||||
#else
|
||||
static void wm8962_init_beep(struct snd_soc_codec *codec)
|
||||
{
|
||||
}
|
||||
|
||||
static void wm8962_free_beep(struct snd_soc_codec *codec)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void wm8962_set_gpio_mode(struct wm8962_priv *wm8962, int gpio)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ config SND_DAVINCI_SOC_GENERIC_EVM
|
|||
|
||||
config SND_AM33XX_SOC_EVM
|
||||
tristate "SoC Audio for the AM33XX chip based boards"
|
||||
depends on SND_DAVINCI_SOC && SOC_AM33XX
|
||||
depends on SND_DAVINCI_SOC && SOC_AM33XX && I2C
|
||||
select SND_DAVINCI_SOC_GENERIC_EVM
|
||||
help
|
||||
Say Y or M if you want to add support for SoC audio on AM33XX
|
||||
|
@ -28,7 +28,7 @@ config SND_AM33XX_SOC_EVM
|
|||
|
||||
config SND_DAVINCI_SOC_EVM
|
||||
tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
|
||||
depends on SND_DAVINCI_SOC
|
||||
depends on SND_DAVINCI_SOC && I2C
|
||||
depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
|
||||
select SND_DAVINCI_SOC_GENERIC_EVM
|
||||
help
|
||||
|
@ -56,7 +56,7 @@ endchoice
|
|||
|
||||
config SND_DM6467_SOC_EVM
|
||||
tristate "SoC Audio support for DaVinci DM6467 EVM"
|
||||
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM
|
||||
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM && I2C
|
||||
select SND_DAVINCI_SOC_GENERIC_EVM
|
||||
select SND_SOC_SPDIF
|
||||
|
||||
|
@ -65,7 +65,7 @@ config SND_DM6467_SOC_EVM
|
|||
|
||||
config SND_DA830_SOC_EVM
|
||||
tristate "SoC Audio support for DA830/OMAP-L137 EVM"
|
||||
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM
|
||||
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM && I2C
|
||||
select SND_DAVINCI_SOC_GENERIC_EVM
|
||||
|
||||
help
|
||||
|
@ -74,7 +74,7 @@ config SND_DA830_SOC_EVM
|
|||
|
||||
config SND_DA850_SOC_EVM
|
||||
tristate "SoC Audio support for DA850/OMAP-L138 EVM"
|
||||
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM
|
||||
depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM && I2C
|
||||
select SND_DAVINCI_SOC_GENERIC_EVM
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on TI
|
||||
|
|
|
@ -757,7 +757,6 @@ static int davinci_i2s_remove(struct platform_device *pdev)
|
|||
struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
davinci_soc_platform_unregister(&pdev->dev);
|
||||
|
||||
clk_disable(dev->clk);
|
||||
clk_put(dev->clk);
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
|
||||
#include "davinci-pcm.h"
|
||||
#include "davinci-mcasp.h"
|
||||
#include "../omap/omap-pcm.h"
|
||||
|
||||
#define MCASP_MAX_AFIFO_DEPTH 64
|
||||
|
||||
struct davinci_mcasp_context {
|
||||
u32 txfmtctl;
|
||||
|
@ -269,25 +272,51 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
|||
{
|
||||
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
int ret = 0;
|
||||
u32 data_delay;
|
||||
bool fs_pol_rising;
|
||||
bool inv_fs = false;
|
||||
|
||||
pm_runtime_get_sync(mcasp->dev);
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
|
||||
/* 1st data bit occur one ACLK cycle after the frame sync */
|
||||
data_delay = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
case SND_SOC_DAIFMT_AC97:
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
|
||||
/* No delay after FS */
|
||||
data_delay = 0;
|
||||
break;
|
||||
default:
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
/* configure a full-word SYNC pulse (LRCLK) */
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
|
||||
|
||||
/* make 1st data bit occur one ACLK cycle after the frame sync */
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(1));
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(1));
|
||||
/* 1st data bit occur one ACLK cycle after the frame sync */
|
||||
data_delay = 1;
|
||||
/* FS need to be inverted */
|
||||
inv_fs = true;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
/* configure a full-word SYNC pulse (LRCLK) */
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
|
||||
/* No delay after FS */
|
||||
data_delay = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay),
|
||||
FSXDLY(3));
|
||||
mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(data_delay),
|
||||
FSRDLY(3));
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
/* codec is clock and frame slave */
|
||||
|
@ -325,7 +354,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
|||
ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
|
||||
mcasp->bclk_master = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
@ -334,39 +362,38 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
|||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
|
||||
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
|
||||
fs_pol_rising = true;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_NB_IF:
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
|
||||
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
|
||||
fs_pol_rising = false;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_IB_IF:
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
|
||||
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
|
||||
fs_pol_rising = false;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
|
||||
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
|
||||
fs_pol_rising = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (inv_fs)
|
||||
fs_pol_rising = !fs_pol_rising;
|
||||
|
||||
if (fs_pol_rising) {
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
|
||||
} else {
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
|
||||
}
|
||||
out:
|
||||
pm_runtime_put_sync(mcasp->dev);
|
||||
|
@ -464,17 +491,19 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
|
|||
}
|
||||
|
||||
static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
|
||||
int channels)
|
||||
int period_words, int channels)
|
||||
{
|
||||
struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream];
|
||||
struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream];
|
||||
int i;
|
||||
u8 tx_ser = 0;
|
||||
u8 rx_ser = 0;
|
||||
u8 ser;
|
||||
u8 slots = mcasp->tdm_slots;
|
||||
u8 max_active_serializers = (channels + slots - 1) / slots;
|
||||
int active_serializers, numevt, n;
|
||||
u32 reg;
|
||||
/* Default configuration */
|
||||
if (mcasp->version != MCASP_VERSION_4)
|
||||
if (mcasp->version < MCASP_VERSION_3)
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
|
||||
|
||||
/* All PINS as McASP */
|
||||
|
@ -505,37 +534,71 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
|
|||
}
|
||||
}
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
ser = tx_ser;
|
||||
else
|
||||
ser = rx_ser;
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
active_serializers = tx_ser;
|
||||
numevt = mcasp->txnumevt;
|
||||
reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
|
||||
} else {
|
||||
active_serializers = rx_ser;
|
||||
numevt = mcasp->rxnumevt;
|
||||
reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
|
||||
}
|
||||
|
||||
if (ser < max_active_serializers) {
|
||||
if (active_serializers < max_active_serializers) {
|
||||
dev_warn(mcasp->dev, "stream has more channels (%d) than are "
|
||||
"enabled in mcasp (%d)\n", channels, ser * slots);
|
||||
"enabled in mcasp (%d)\n", channels,
|
||||
active_serializers * slots);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mcasp->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
if (mcasp->txnumevt * tx_ser > 64)
|
||||
mcasp->txnumevt = 1;
|
||||
|
||||
reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
|
||||
mcasp_mod_bits(mcasp, reg, tx_ser, NUMDMA_MASK);
|
||||
mcasp_mod_bits(mcasp, reg, ((mcasp->txnumevt * tx_ser) << 8),
|
||||
NUMEVT_MASK);
|
||||
/* AFIFO is not in use */
|
||||
if (!numevt) {
|
||||
/* Configure the burst size for platform drivers */
|
||||
if (active_serializers > 1) {
|
||||
/*
|
||||
* If more than one serializers are in use we have one
|
||||
* DMA request to provide data for all serializers.
|
||||
* For example if three serializers are enabled the DMA
|
||||
* need to transfer three words per DMA request.
|
||||
*/
|
||||
dma_params->fifo_level = active_serializers;
|
||||
dma_data->maxburst = active_serializers;
|
||||
} else {
|
||||
dma_params->fifo_level = 0;
|
||||
dma_data->maxburst = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mcasp->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
if (mcasp->rxnumevt * rx_ser > 64)
|
||||
mcasp->rxnumevt = 1;
|
||||
|
||||
reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
|
||||
mcasp_mod_bits(mcasp, reg, rx_ser, NUMDMA_MASK);
|
||||
mcasp_mod_bits(mcasp, reg, ((mcasp->rxnumevt * rx_ser) << 8),
|
||||
NUMEVT_MASK);
|
||||
if (period_words % active_serializers) {
|
||||
dev_err(mcasp->dev, "Invalid combination of period words and "
|
||||
"active serializers: %d, %d\n", period_words,
|
||||
active_serializers);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the optimal AFIFO depth for platform side:
|
||||
* The number of words for numevt need to be in steps of active
|
||||
* serializers.
|
||||
*/
|
||||
n = numevt % active_serializers;
|
||||
if (n)
|
||||
numevt += (active_serializers - n);
|
||||
while (period_words % numevt && numevt > 0)
|
||||
numevt -= active_serializers;
|
||||
if (numevt <= 0)
|
||||
numevt = active_serializers;
|
||||
|
||||
mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK);
|
||||
mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK);
|
||||
|
||||
/* Configure the burst size for platform drivers */
|
||||
if (numevt == 1)
|
||||
numevt = 0;
|
||||
dma_params->fifo_level = numevt;
|
||||
dma_data->maxburst = numevt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -607,27 +670,24 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
|
|||
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct davinci_pcm_dma_params *dma_params =
|
||||
&mcasp->dma_params[substream->stream];
|
||||
struct snd_dmaengine_dai_dma_data *dma_data =
|
||||
&mcasp->dma_data[substream->stream];
|
||||
int word_length;
|
||||
u8 fifo_level;
|
||||
u8 slots = mcasp->tdm_slots;
|
||||
u8 active_serializers;
|
||||
int channels = params_channels(params);
|
||||
int period_size = params_period_size(params);
|
||||
int ret;
|
||||
|
||||
/* If mcasp is BCLK master we need to set BCLK divider */
|
||||
if (mcasp->bclk_master) {
|
||||
unsigned int bclk_freq = snd_soc_params_to_bclk(params);
|
||||
if (mcasp->sysclk_freq % bclk_freq != 0) {
|
||||
dev_err(mcasp->dev, "Can't produce requred BCLK\n");
|
||||
dev_err(mcasp->dev, "Can't produce required BCLK\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
davinci_mcasp_set_clkdiv(
|
||||
cpu_dai, 1, mcasp->sysclk_freq / bclk_freq);
|
||||
}
|
||||
|
||||
ret = mcasp_common_hw_param(mcasp, substream->stream, channels);
|
||||
ret = mcasp_common_hw_param(mcasp, substream->stream,
|
||||
period_size * channels, channels);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -671,21 +731,11 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate FIFO level */
|
||||
active_serializers = (channels + slots - 1) / slots;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
fifo_level = mcasp->txnumevt * active_serializers;
|
||||
else
|
||||
fifo_level = mcasp->rxnumevt * active_serializers;
|
||||
|
||||
if (mcasp->version == MCASP_VERSION_2 && !fifo_level)
|
||||
if (mcasp->version == MCASP_VERSION_2 && !dma_params->fifo_level)
|
||||
dma_params->acnt = 4;
|
||||
else
|
||||
dma_params->acnt = dma_params->data_type;
|
||||
|
||||
dma_params->fifo_level = fifo_level;
|
||||
dma_data->maxburst = fifo_level;
|
||||
|
||||
davinci_config_channel_size(mcasp, word_length);
|
||||
|
||||
return 0;
|
||||
|
@ -716,22 +766,7 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (mcasp->version == MCASP_VERSION_4)
|
||||
snd_soc_dai_set_dma_data(dai, substream,
|
||||
&mcasp->dma_data[substream->stream]);
|
||||
else
|
||||
snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
|
||||
.startup = davinci_mcasp_startup,
|
||||
.trigger = davinci_mcasp_trigger,
|
||||
.hw_params = davinci_mcasp_hw_params,
|
||||
.set_fmt = davinci_mcasp_set_dai_fmt,
|
||||
|
@ -739,6 +774,25 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
|
|||
.set_sysclk = davinci_mcasp_set_sysclk,
|
||||
};
|
||||
|
||||
static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (mcasp->version == MCASP_VERSION_4) {
|
||||
/* Using dmaengine PCM */
|
||||
dai->playback_dma_data =
|
||||
&mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
dai->capture_dma_data =
|
||||
&mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
|
||||
} else {
|
||||
/* Using davinci-pcm */
|
||||
dai->playback_dma_data = mcasp->dma_params;
|
||||
dai->capture_dma_data = mcasp->dma_params;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
|
||||
{
|
||||
|
@ -792,6 +846,7 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
|
|||
static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
|
||||
{
|
||||
.name = "davinci-mcasp.0",
|
||||
.probe = davinci_mcasp_dai_probe,
|
||||
.suspend = davinci_mcasp_suspend,
|
||||
.resume = davinci_mcasp_resume,
|
||||
.playback = {
|
||||
|
@ -811,6 +866,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
|
|||
},
|
||||
{
|
||||
.name = "davinci-mcasp.1",
|
||||
.probe = davinci_mcasp_dai_probe,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 384,
|
||||
|
@ -1078,7 +1134,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
|
|||
if (!mcasp->base) {
|
||||
dev_err(&pdev->dev, "ioremap failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_release_clk;
|
||||
goto err;
|
||||
}
|
||||
|
||||
mcasp->op_mode = pdata->op_mode;
|
||||
|
@ -1159,25 +1215,37 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
|
|||
|
||||
mcasp_reparent_fck(pdev);
|
||||
|
||||
ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
|
||||
ret = devm_snd_soc_register_component(&pdev->dev,
|
||||
&davinci_mcasp_component,
|
||||
&davinci_mcasp_dai[pdata->op_mode], 1);
|
||||
|
||||
if (ret != 0)
|
||||
goto err_release_clk;
|
||||
goto err;
|
||||
|
||||
if (mcasp->version != MCASP_VERSION_4) {
|
||||
switch (mcasp->version) {
|
||||
case MCASP_VERSION_1:
|
||||
case MCASP_VERSION_2:
|
||||
case MCASP_VERSION_3:
|
||||
ret = davinci_soc_platform_register(&pdev->dev);
|
||||
break;
|
||||
case MCASP_VERSION_4:
|
||||
ret = omap_pcm_platform_register(&pdev->dev);
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Invalid McASP version: %d\n",
|
||||
mcasp->version);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
|
||||
goto err_unregister_component;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_component:
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
err_release_clk:
|
||||
err:
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
|
@ -1185,12 +1253,6 @@ err_release_clk:
|
|||
|
||||
static int davinci_mcasp_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
if (mcasp->version != MCASP_VERSION_4)
|
||||
davinci_soc_platform_unregister(&pdev->dev);
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
|
|
|
@ -283,6 +283,7 @@
|
|||
*/
|
||||
#define FIFO_ENABLE BIT(16)
|
||||
#define NUMEVT_MASK (0xFF << 8)
|
||||
#define NUMEVT(x) (((x) & 0xFF) << 8)
|
||||
#define NUMDMA_MASK (0xFF)
|
||||
|
||||
#endif /* DAVINCI_MCASP_H */
|
||||
|
|
|
@ -852,16 +852,10 @@ static struct snd_soc_platform_driver davinci_soc_platform = {
|
|||
|
||||
int davinci_soc_platform_register(struct device *dev)
|
||||
{
|
||||
return snd_soc_register_platform(dev, &davinci_soc_platform);
|
||||
return devm_snd_soc_register_platform(dev, &davinci_soc_platform);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(davinci_soc_platform_register);
|
||||
|
||||
void davinci_soc_platform_unregister(struct device *dev)
|
||||
{
|
||||
snd_soc_unregister_platform(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister);
|
||||
|
||||
MODULE_AUTHOR("Vladimir Barinov");
|
||||
MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -29,7 +29,13 @@ struct davinci_pcm_dma_params {
|
|||
unsigned int fifo_level;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_DAVINCI_SOC)
|
||||
int davinci_soc_platform_register(struct device *dev);
|
||||
void davinci_soc_platform_unregister(struct device *dev);
|
||||
#else
|
||||
static inline int davinci_soc_platform_register(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SND_DAVINCI_SOC */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -258,7 +258,6 @@ static int davinci_vcif_probe(struct platform_device *pdev)
|
|||
static int davinci_vcif_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
davinci_soc_platform_unregister(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ config SND_SOC_EUKREA_TLV320
|
|||
|
||||
config SND_SOC_IMX_WM8962
|
||||
tristate "SoC Audio support for i.MX boards with wm8962"
|
||||
depends on OF && I2C
|
||||
depends on OF && I2C && INPUT
|
||||
select SND_SOC_WM8962
|
||||
select SND_SOC_IMX_PCM_DMA
|
||||
select SND_SOC_IMX_AUDMUX
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "omap-mcbsp.h"
|
||||
#include "../codecs/cx20442.h"
|
||||
|
||||
|
||||
/* Board specific DAPM widgets */
|
||||
static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
|
||||
/* Handset */
|
||||
|
@ -90,17 +89,23 @@ static const unsigned short ams_delta_audio_mode_pins[] = {
|
|||
|
||||
static unsigned short ams_delta_audio_agc;
|
||||
|
||||
/*
|
||||
* Used for passing a codec structure pointer
|
||||
* from the board initialization code to the tty line discipline.
|
||||
*/
|
||||
static struct snd_soc_codec *cx20442_codec;
|
||||
|
||||
static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = &card->dapm;
|
||||
struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
|
||||
unsigned short pins;
|
||||
int pin, changed = 0;
|
||||
|
||||
/* Refuse any mode changes if we are not able to control the codec. */
|
||||
if (!codec->hw_write)
|
||||
if (!cx20442_codec->hw_write)
|
||||
return -EUNATCH;
|
||||
|
||||
if (ucontrol->value.enumerated.item[0] >= control->items)
|
||||
|
@ -166,8 +171,8 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
|
|||
static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = &card->dapm;
|
||||
unsigned short pins, mode;
|
||||
|
||||
pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") <<
|
||||
|
@ -270,12 +275,6 @@ static void cx81801_timeout(unsigned long data)
|
|||
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for passing a codec structure pointer
|
||||
* from the board initialization code to the tty line discipline.
|
||||
*/
|
||||
static struct snd_soc_codec *cx20442_codec;
|
||||
|
||||
/* Line discipline .open() */
|
||||
static int cx81801_open(struct tty_struct *tty)
|
||||
{
|
||||
|
@ -302,7 +301,7 @@ static int cx81801_open(struct tty_struct *tty)
|
|||
static void cx81801_close(struct tty_struct *tty)
|
||||
{
|
||||
struct snd_soc_codec *codec = tty->disc_data;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
struct snd_soc_dapm_context *dapm = &codec->card->dapm;
|
||||
|
||||
del_timer_sync(&cx81801_timer);
|
||||
|
||||
|
@ -475,15 +474,14 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream)
|
|||
|
||||
static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct snd_soc_dapm_context *dapm = &card->dapm;
|
||||
int ret;
|
||||
/* Codec is ready, now add/activate board specific controls */
|
||||
|
||||
/* Store a pointer to the codec structure for tty ldisc use */
|
||||
cx20442_codec = codec;
|
||||
cx20442_codec = rtd->codec;
|
||||
|
||||
/* Set up digital mute if not provided by the codec */
|
||||
if (!codec_dai->driver->ops) {
|
||||
|
@ -520,39 +518,12 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Add board specific DAPM widgets and routes */
|
||||
ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets,
|
||||
ARRAY_SIZE(ams_delta_dapm_widgets));
|
||||
if (ret) {
|
||||
dev_warn(card->dev,
|
||||
"Failed to register DAPM controls, "
|
||||
"will continue without any.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map,
|
||||
ARRAY_SIZE(ams_delta_audio_map));
|
||||
if (ret) {
|
||||
dev_warn(card->dev,
|
||||
"Failed to set up DAPM routes, "
|
||||
"will continue with codec default map.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set up initial pin constellation */
|
||||
snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
|
||||
snd_soc_dapm_disable_pin(dapm, "Speaker");
|
||||
snd_soc_dapm_disable_pin(dapm, "AGCIN");
|
||||
snd_soc_dapm_disable_pin(dapm, "AGCOUT");
|
||||
|
||||
/* Add virtual switch */
|
||||
ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls,
|
||||
ARRAY_SIZE(ams_delta_audio_controls));
|
||||
if (ret)
|
||||
dev_warn(card->dev,
|
||||
"Failed to register audio mode control, "
|
||||
"will continue without it.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -574,6 +545,13 @@ static struct snd_soc_card ams_delta_audio_card = {
|
|||
.owner = THIS_MODULE,
|
||||
.dai_link = &ams_delta_dai_link,
|
||||
.num_links = 1,
|
||||
|
||||
.controls = ams_delta_audio_controls,
|
||||
.num_controls = ARRAY_SIZE(ams_delta_audio_controls),
|
||||
.dapm_widgets = ams_delta_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(ams_delta_dapm_widgets),
|
||||
.dapm_routes = ams_delta_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(ams_delta_audio_map),
|
||||
};
|
||||
|
||||
/* Module init/exit */
|
||||
|
|
|
@ -232,6 +232,12 @@ static struct snd_soc_platform_driver omap_soc_platform = {
|
|||
.pcm_free = omap_pcm_free_dma_buffers,
|
||||
};
|
||||
|
||||
int omap_pcm_platform_register(struct device *dev)
|
||||
{
|
||||
return devm_snd_soc_register_platform(dev, &omap_soc_platform);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_pcm_platform_register);
|
||||
|
||||
static int omap_pcm_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_platform(&pdev->dev,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* omap-pcm.h - OMAP PCM driver
|
||||
*
|
||||
* Copyright (C) 2014 Texas Instruments, Inc.
|
||||
*
|
||||
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __OMAP_PCM_H__
|
||||
#define __OMAP_PCM_H__
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_OMAP_SOC)
|
||||
int omap_pcm_platform_register(struct device *dev);
|
||||
#else
|
||||
static inline int omap_pcm_platform_register(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SND_OMAP_SOC */
|
||||
|
||||
#endif /* __OMAP_PCM_H__ */
|
|
@ -121,7 +121,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
|
|||
* |A| <~~clk~~+
|
||||
* |P| <--- TWL4030 <--------- Line In and MICs
|
||||
*/
|
||||
static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
|
||||
static const struct snd_soc_dapm_widget omap3pandora_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM,
|
||||
0, 0, omap3pandora_dac_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
|
||||
|
@ -130,22 +130,18 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_LINE("Line Out", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MIC("Mic (internal)", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic (external)", NULL),
|
||||
SND_SOC_DAPM_LINE("Line In", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
|
||||
static const struct snd_soc_dapm_route omap3pandora_map[] = {
|
||||
{"PCM DAC", NULL, "APLL Enable"},
|
||||
{"Headphone Amplifier", NULL, "PCM DAC"},
|
||||
{"Line Out", NULL, "PCM DAC"},
|
||||
{"Headphone Jack", NULL, "Headphone Amplifier"},
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
|
||||
{"AUXL", NULL, "Line In"},
|
||||
{"AUXR", NULL, "Line In"},
|
||||
|
||||
|
@ -160,7 +156,6 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
|
|||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
int ret;
|
||||
|
||||
/* All TWL4030 output pins are floating */
|
||||
snd_soc_dapm_nc_pin(dapm, "EARPIECE");
|
||||
|
@ -174,20 +169,13 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
|
|||
snd_soc_dapm_nc_pin(dapm, "HFR");
|
||||
snd_soc_dapm_nc_pin(dapm, "VIBRA");
|
||||
|
||||
ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets,
|
||||
ARRAY_SIZE(omap3pandora_out_dapm_widgets));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map,
|
||||
ARRAY_SIZE(omap3pandora_out_map));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
int ret;
|
||||
|
||||
/* Not comnnected */
|
||||
snd_soc_dapm_nc_pin(dapm, "HSMIC");
|
||||
|
@ -195,13 +183,7 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
|
|||
snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
|
||||
snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
|
||||
|
||||
ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets,
|
||||
ARRAY_SIZE(omap3pandora_in_dapm_widgets));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map,
|
||||
ARRAY_SIZE(omap3pandora_in_map));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops omap3pandora_ops = {
|
||||
|
@ -241,6 +223,11 @@ static struct snd_soc_card snd_soc_card_omap3pandora = {
|
|||
.owner = THIS_MODULE,
|
||||
.dai_link = omap3pandora_dai,
|
||||
.num_links = ARRAY_SIZE(omap3pandora_dai),
|
||||
|
||||
.dapm_widgets = omap3pandora_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(omap3pandora_dapm_widgets),
|
||||
.dapm_routes = omap3pandora_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(omap3pandora_map),
|
||||
};
|
||||
|
||||
static struct platform_device *omap3pandora_snd_device;
|
||||
|
|
|
@ -237,9 +237,6 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
|
||||
SND_SOC_DAPM_MIC("HS Mic", NULL),
|
||||
SND_SOC_DAPM_LINE("FM Transmitter", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = {
|
||||
SND_SOC_DAPM_SPK("Earphone", NULL),
|
||||
};
|
||||
|
||||
|
@ -253,9 +250,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
|||
|
||||
{"DMic Rate 64", NULL, "Mic Bias"},
|
||||
{"Mic Bias", NULL, "DMic"},
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_mapb[] = {
|
||||
{"b LINE2R", NULL, "MONO_LOUT"},
|
||||
{"Earphone", NULL, "b HPLOUT"},
|
||||
|
||||
|
@ -281,9 +276,6 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
|
|||
SOC_ENUM_EXT("Jack Function", rx51_enum[2],
|
||||
rx51_get_jack, rx51_set_jack),
|
||||
SOC_DAPM_PIN_SWITCH("FM Transmitter"),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new aic34_rx51_controlsb[] = {
|
||||
SOC_DAPM_PIN_SWITCH("Earphone"),
|
||||
};
|
||||
|
||||
|
@ -298,19 +290,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
|
|||
snd_soc_dapm_nc_pin(dapm, "MIC3R");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINE1R");
|
||||
|
||||
/* Add RX-51 specific controls */
|
||||
err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls,
|
||||
ARRAY_SIZE(aic34_rx51_controls));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Add RX-51 specific widgets */
|
||||
snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets,
|
||||
ARRAY_SIZE(aic34_dapm_widgets));
|
||||
|
||||
/* Set up RX-51 specific audio path audio_map */
|
||||
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
|
||||
|
||||
err = tpa6130a2_add_controls(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -333,24 +312,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb,
|
||||
ARRAY_SIZE(aic34_rx51_controlsb));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb,
|
||||
ARRAY_SIZE(aic34_dapm_widgetsb));
|
||||
if (err < 0)
|
||||
return 0;
|
||||
|
||||
return snd_soc_dapm_add_routes(dapm, audio_mapb,
|
||||
ARRAY_SIZE(audio_mapb));
|
||||
}
|
||||
|
||||
/* Digital audio interface glue - connects codec <--> CPU */
|
||||
static struct snd_soc_dai_link rx51_dai[] = {
|
||||
{
|
||||
|
@ -371,7 +332,6 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
|
|||
{
|
||||
.name = "TLV320AIC34b",
|
||||
.codec_name = "tlv320aic3x-codec.2-0019",
|
||||
.init = rx51_aic34b_init,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -392,6 +352,13 @@ static struct snd_soc_card rx51_sound_card = {
|
|||
.num_aux_devs = ARRAY_SIZE(rx51_aux_dev),
|
||||
.codec_conf = rx51_codec_conf,
|
||||
.num_configs = ARRAY_SIZE(rx51_codec_conf),
|
||||
|
||||
.controls = aic34_rx51_controls,
|
||||
.num_controls = ARRAY_SIZE(aic34_rx51_controls),
|
||||
.dapm_widgets = aic34_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(aic34_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
};
|
||||
|
||||
static struct platform_device *rx51_snd_device;
|
||||
|
|
|
@ -204,7 +204,7 @@ config SND_SOC_SPEYSIDE
|
|||
|
||||
config SND_SOC_TOBERMORY
|
||||
tristate "Audio support for Wolfson Tobermory"
|
||||
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
|
||||
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && INPUT
|
||||
select SND_SAMSUNG_I2S
|
||||
select SND_SOC_WM8962
|
||||
|
||||
|
|
|
@ -52,6 +52,40 @@ int devm_snd_soc_register_component(struct device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(devm_snd_soc_register_component);
|
||||
|
||||
static void devm_platform_release(struct device *dev, void *res)
|
||||
{
|
||||
snd_soc_unregister_platform(*(struct device **)res);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_snd_soc_register_platform - resource managed platform registration
|
||||
* @dev: Device used to manage platform
|
||||
* @platform: platform to register
|
||||
*
|
||||
* Register a platform driver with automatic unregistration when the device is
|
||||
* unregistered.
|
||||
*/
|
||||
int devm_snd_soc_register_platform(struct device *dev,
|
||||
const struct snd_soc_platform_driver *platform_drv)
|
||||
{
|
||||
struct device **ptr;
|
||||
int ret;
|
||||
|
||||
ptr = devres_alloc(devm_platform_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = snd_soc_register_platform(dev, platform_drv);
|
||||
if (ret == 0) {
|
||||
*ptr = dev;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void devm_card_release(struct device *dev, void *res)
|
||||
{
|
||||
snd_soc_unregister_card(*(struct snd_soc_card **)res);
|
||||
|
|
Загрузка…
Ссылка в новой задаче