mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 09:13:38 +00:00
ASoC: codecs: adau1373: drop platform data
Merge series from Nuno Sa <nuno.sa@analog.com>: Support the powerdown GPIO on ADAU1373.
This commit is contained in:
commit
3f58985e43
111
Documentation/devicetree/bindings/sound/adi,adau1373.yaml
Normal file
111
Documentation/devicetree/bindings/sound/adi,adau1373.yaml
Normal file
@ -0,0 +1,111 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/adi,adau1373.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADAU1373 CODEC
|
||||
|
||||
maintainers:
|
||||
- Nuno Sá <nuno.sa@analog.com>
|
||||
|
||||
description: |
|
||||
Analog Devices ADAU1373 Low power codec with speaker and headphone amplifiers.
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ADAU1373.pdf
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,adau1373
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
powerdown-gpios:
|
||||
description: GPIO used for hardware power-down.
|
||||
maxItems: 1
|
||||
|
||||
adi,micbias1-microvolt:
|
||||
description:
|
||||
This property sets the microphone bias voltage for the first microphone.
|
||||
enum: [1800000, 2200000, 2600000, 2900000]
|
||||
default: 2900000
|
||||
|
||||
adi,micbias2-microvolt:
|
||||
description:
|
||||
This property sets the microphone bias voltage for the second microphone.
|
||||
enum: [1800000, 2200000, 2600000, 2900000]
|
||||
default: 2900000
|
||||
|
||||
adi,input1-differential:
|
||||
description: This property sets the first analog input as differential.
|
||||
type: boolean
|
||||
|
||||
adi,input2-differential:
|
||||
description: This property sets the second analog input as differential.
|
||||
type: boolean
|
||||
|
||||
adi,input3-differential:
|
||||
description: This property sets the third analog input as differential.
|
||||
type: boolean
|
||||
|
||||
adi,input4-differential:
|
||||
description: This property sets the fourth analog input as differential.
|
||||
type: boolean
|
||||
|
||||
adi,lineout-differential:
|
||||
description: This property sets the line output as differential.
|
||||
type: boolean
|
||||
|
||||
adi,lineout-gnd-sense:
|
||||
description: This property enables the line output ground sense control.
|
||||
type: boolean
|
||||
|
||||
adi,drc-settings:
|
||||
description:
|
||||
This setting is used to control the dynamic range of the signal. The
|
||||
device provides a maximum of three full band DRCs with 13 entries each.
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
oneOf:
|
||||
- minItems: 13
|
||||
maxItems: 13
|
||||
- minItems: 26
|
||||
maxItems: 26
|
||||
- minItems: 39
|
||||
maxItems: 39
|
||||
|
||||
required:
|
||||
- "#sound-dai-cells"
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
audio-codec@1a {
|
||||
compatible = "adi,adau1373";
|
||||
reg = <0x1a>;
|
||||
#sound-dai-cells = <0>;
|
||||
powerdown-gpios = <&gpio 100 GPIO_ACTIVE_LOW>;
|
||||
adi,input2-differential;
|
||||
adi,input1-differential;
|
||||
adi,lineout-differential;
|
||||
adi,micbias2-microvolt = <1800000>;
|
||||
adi,drc-settings = /bits/ 8 <
|
||||
0xff 0xff 0x1 0x2 0xa 0xa 0xd 0x1 0xff 0xff 0x5 0xd 0xff
|
||||
>;
|
||||
};
|
||||
};
|
||||
...
|
@ -1521,6 +1521,7 @@ L: linux-sound@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://wiki.analog.com/
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/sound/adi,*
|
||||
F: sound/soc/codecs/ad1*
|
||||
F: sound/soc/codecs/ad7*
|
||||
F: sound/soc/codecs/adau*
|
||||
|
@ -1,33 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Analog Devices ADAU1373 Audio Codec drive
|
||||
*
|
||||
* Copyright 2011 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_ADAU1373_H__
|
||||
#define __SOUND_ADAU1373_H__
|
||||
|
||||
enum adau1373_micbias_voltage {
|
||||
ADAU1373_MICBIAS_2_9V = 0,
|
||||
ADAU1373_MICBIAS_2_2V = 1,
|
||||
ADAU1373_MICBIAS_2_6V = 2,
|
||||
ADAU1373_MICBIAS_1_8V = 3,
|
||||
};
|
||||
|
||||
#define ADAU1373_DRC_SIZE 13
|
||||
|
||||
struct adau1373_platform_data {
|
||||
bool input_differential[4];
|
||||
bool lineout_differential;
|
||||
bool lineout_ground_sense;
|
||||
|
||||
unsigned int num_drc;
|
||||
uint8_t drc_setting[3][ADAU1373_DRC_SIZE];
|
||||
|
||||
enum adau1373_micbias_voltage micbias1;
|
||||
enum adau1373_micbias_voltage micbias2;
|
||||
};
|
||||
|
||||
#endif
|
@ -465,7 +465,7 @@ config SND_SOC_ADAU1372_SPI
|
||||
select REGMAP_SPI
|
||||
|
||||
config SND_SOC_ADAU1373
|
||||
tristate
|
||||
tristate "Analog Devices ADAU1373 CODEC"
|
||||
depends on I2C
|
||||
select SND_SOC_ADAU_UTILS
|
||||
|
||||
|
@ -8,8 +8,10 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
@ -18,7 +20,6 @@
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/adau1373.h>
|
||||
|
||||
#include "adau1373.h"
|
||||
#include "adau-utils.h"
|
||||
@ -30,9 +31,28 @@ struct adau1373_dai {
|
||||
bool clock_provider;
|
||||
};
|
||||
|
||||
enum adau1373_micbias_voltage {
|
||||
ADAU1373_MICBIAS_2_9V,
|
||||
ADAU1373_MICBIAS_2_2V,
|
||||
ADAU1373_MICBIAS_2_6V,
|
||||
ADAU1373_MICBIAS_1_8V,
|
||||
};
|
||||
|
||||
#define ADAU1373_DRC_SIZE 13
|
||||
|
||||
struct adau1373 {
|
||||
struct regmap *regmap;
|
||||
struct adau1373_dai dais[3];
|
||||
|
||||
bool input_differential[4];
|
||||
bool lineout_differential;
|
||||
bool lineout_ground_sense;
|
||||
|
||||
unsigned int num_drc;
|
||||
u8 drc_setting[3][ADAU1373_DRC_SIZE];
|
||||
|
||||
enum adau1373_micbias_voltage micbias1;
|
||||
enum adau1373_micbias_voltage micbias2;
|
||||
};
|
||||
|
||||
#define ADAU1373_INPUT_MODE 0x00
|
||||
@ -1332,66 +1352,61 @@ static void adau1373_load_drc_settings(struct adau1373 *adau1373,
|
||||
regmap_write(adau1373->regmap, ADAU1373_DRC(nr) + i, drc[i]);
|
||||
}
|
||||
|
||||
static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
|
||||
static int adau1373_get_micbias(unsigned int val,
|
||||
enum adau1373_micbias_voltage *micbias)
|
||||
{
|
||||
switch (micbias) {
|
||||
case ADAU1373_MICBIAS_2_9V:
|
||||
case ADAU1373_MICBIAS_2_2V:
|
||||
case ADAU1373_MICBIAS_2_6V:
|
||||
case ADAU1373_MICBIAS_1_8V:
|
||||
return true;
|
||||
switch (val) {
|
||||
case 2900000:
|
||||
*micbias = ADAU1373_MICBIAS_2_9V;
|
||||
return 0;
|
||||
case 2200000:
|
||||
*micbias = ADAU1373_MICBIAS_2_2V;
|
||||
return 0;
|
||||
case 2600000:
|
||||
*micbias = ADAU1373_MICBIAS_2_6V;
|
||||
return 0;
|
||||
case 1800000:
|
||||
*micbias = ADAU1373_MICBIAS_1_8V;
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int adau1373_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
|
||||
struct adau1373_platform_data *pdata = component->dev->platform_data;
|
||||
bool lineout_differential = false;
|
||||
unsigned int val;
|
||||
int i;
|
||||
|
||||
if (pdata) {
|
||||
if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
|
||||
return -EINVAL;
|
||||
|
||||
if (!adau1373_valid_micbias(pdata->micbias1) ||
|
||||
!adau1373_valid_micbias(pdata->micbias2))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < pdata->num_drc; ++i) {
|
||||
adau1373_load_drc_settings(adau1373, i,
|
||||
pdata->drc_setting[i]);
|
||||
}
|
||||
|
||||
snd_soc_add_component_controls(component, adau1373_drc_controls,
|
||||
pdata->num_drc);
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (pdata->input_differential[i])
|
||||
val |= BIT(i);
|
||||
}
|
||||
regmap_write(adau1373->regmap, ADAU1373_INPUT_MODE, val);
|
||||
|
||||
val = 0;
|
||||
if (pdata->lineout_differential)
|
||||
val |= ADAU1373_OUTPUT_CTRL_LDIFF;
|
||||
if (pdata->lineout_ground_sense)
|
||||
val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
|
||||
regmap_write(adau1373->regmap, ADAU1373_OUTPUT_CTRL, val);
|
||||
|
||||
lineout_differential = pdata->lineout_differential;
|
||||
|
||||
regmap_write(adau1373->regmap, ADAU1373_EP_CTRL,
|
||||
(pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
|
||||
(pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
|
||||
for (i = 0; i < adau1373->num_drc; ++i) {
|
||||
adau1373_load_drc_settings(adau1373, i,
|
||||
adau1373->drc_setting[i]);
|
||||
}
|
||||
|
||||
if (!lineout_differential) {
|
||||
snd_soc_add_component_controls(component, adau1373_drc_controls,
|
||||
adau1373->num_drc);
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(adau1373->input_differential); ++i) {
|
||||
if (adau1373->input_differential[i])
|
||||
val |= BIT(i);
|
||||
}
|
||||
regmap_write(adau1373->regmap, ADAU1373_INPUT_MODE, val);
|
||||
|
||||
val = 0;
|
||||
if (adau1373->lineout_differential)
|
||||
val |= ADAU1373_OUTPUT_CTRL_LDIFF;
|
||||
if (adau1373->lineout_ground_sense)
|
||||
val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
|
||||
|
||||
regmap_write(adau1373->regmap, ADAU1373_OUTPUT_CTRL, val);
|
||||
|
||||
regmap_write(adau1373->regmap, ADAU1373_EP_CTRL,
|
||||
(adau1373->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
|
||||
(adau1373->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
|
||||
|
||||
if (!adau1373->lineout_differential) {
|
||||
snd_soc_add_component_controls(component, adau1373_lineout2_controls,
|
||||
ARRAY_SIZE(adau1373_lineout2_controls));
|
||||
}
|
||||
@ -1471,9 +1486,74 @@ static const struct snd_soc_component_driver adau1373_component_driver = {
|
||||
.endianness = 1,
|
||||
};
|
||||
|
||||
static void adau1373_reset(void *reset_gpio)
|
||||
{
|
||||
gpiod_set_value_cansleep(reset_gpio, 1);
|
||||
}
|
||||
|
||||
static int adau1373_parse_fw(struct device *dev, struct adau1373 *adau1373)
|
||||
{
|
||||
int ret, drc_count;
|
||||
unsigned int val;
|
||||
|
||||
if (device_property_present(dev, "adi,input1-differential"))
|
||||
adau1373->input_differential[0] = true;
|
||||
if (device_property_present(dev, "adi,input2-differential"))
|
||||
adau1373->input_differential[1] = true;
|
||||
if (device_property_present(dev, "adi,input3-differential"))
|
||||
adau1373->input_differential[2] = true;
|
||||
if (device_property_present(dev, "adi,input4-differential"))
|
||||
adau1373->input_differential[3] = true;
|
||||
|
||||
if (device_property_present(dev, "adi,lineout-differential"))
|
||||
adau1373->lineout_differential = true;
|
||||
if (device_property_present(dev, "adi,lineout-gnd-sense"))
|
||||
adau1373->lineout_ground_sense = true;
|
||||
|
||||
ret = device_property_read_u32(dev, "adi,micbias1-microvolt", &val);
|
||||
if (!ret) {
|
||||
ret = adau1373_get_micbias(val, &adau1373->micbias1);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to get micbias1(%u)\n", val);
|
||||
}
|
||||
|
||||
ret = device_property_read_u32(dev, "adi,micbias2-microvolt", &val);
|
||||
if (!ret) {
|
||||
ret = adau1373_get_micbias(val, &adau1373->micbias2);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to get micbias2(%u)\n", val);
|
||||
}
|
||||
|
||||
drc_count = device_property_count_u8(dev, "adi,drc-settings");
|
||||
if (drc_count < 0)
|
||||
return 0;
|
||||
if (drc_count % ADAU1373_DRC_SIZE != 0)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"DRC count(%u) not multiple of %u\n",
|
||||
drc_count, ADAU1373_DRC_SIZE);
|
||||
|
||||
adau1373->num_drc = drc_count / ADAU1373_DRC_SIZE;
|
||||
if (adau1373->num_drc > ARRAY_SIZE(adau1373->drc_setting))
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"Too many DRC settings(%u)\n",
|
||||
adau1373->num_drc);
|
||||
|
||||
ret = device_property_read_u8_array(dev, "adi,drc-settings",
|
||||
(u8 *)&adau1373->drc_setting[0],
|
||||
drc_count);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to read DRC settings\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adau1373_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct adau1373 *adau1373;
|
||||
struct gpio_desc *gpiod;
|
||||
int ret;
|
||||
|
||||
adau1373 = devm_kzalloc(&client->dev, sizeof(*adau1373), GFP_KERNEL);
|
||||
@ -1485,10 +1565,33 @@ static int adau1373_i2c_probe(struct i2c_client *client)
|
||||
if (IS_ERR(adau1373->regmap))
|
||||
return PTR_ERR(adau1373->regmap);
|
||||
|
||||
regmap_write(adau1373->regmap, ADAU1373_SOFT_RESET, 0x00);
|
||||
/*
|
||||
* If the powerdown GPIO is specified, we use it for reset. Otherwise
|
||||
* a software reset is done.
|
||||
*/
|
||||
gpiod = devm_gpiod_get_optional(&client->dev, "powerdown",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(gpiod))
|
||||
return PTR_ERR(gpiod);
|
||||
|
||||
if (gpiod) {
|
||||
gpiod_set_value_cansleep(gpiod, 0);
|
||||
fsleep(10);
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev, adau1373_reset,
|
||||
gpiod);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
regmap_write(adau1373->regmap, ADAU1373_SOFT_RESET, 0x00);
|
||||
}
|
||||
|
||||
dev_set_drvdata(&client->dev, adau1373);
|
||||
|
||||
ret = adau1373_parse_fw(&client->dev, adau1373);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_snd_soc_register_component(&client->dev,
|
||||
&adau1373_component_driver,
|
||||
adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
|
||||
@ -1501,9 +1604,16 @@ static const struct i2c_device_id adau1373_i2c_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id);
|
||||
|
||||
static const struct of_device_id adau1373_of_match[] = {
|
||||
{ .compatible = "adi,adau1373", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adau1373_of_match);
|
||||
|
||||
static struct i2c_driver adau1373_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "adau1373",
|
||||
.of_match_table = adau1373_of_match,
|
||||
},
|
||||
.probe = adau1373_i2c_probe,
|
||||
.id_table = adau1373_i2c_id,
|
||||
|
Loading…
Reference in New Issue
Block a user